Добрый день, Задача: разбить столбец таблицы MYSQL на несколько столбцов (date, key, V) по содержимому. Исходные данные: ------------------------------------------------------------------------------------------ date29052019;5232.5189;N;06245.9387;E;0;306;A00012345;V123 ------------------------------------------------------------------------------------------ Необходимый результат: ------------------------------------------------------------------------------------------- ! date ! map ! key ! V ! !-------------------!---------------------------------------------!---------------!--------! ! 29052019 !5232.5189;N;06245.9387;E;0;306!A00012345!V123! !-------------------!---------------------------------------------!---------------!--------! Думаю двигаться в направлении: 1. Исходя из данных strlen (он может быть разный) определить размер массива; 2. Дальше не знаю).
PHP: <?php $str = 'date29052019;5232.5189;N;06245.9387;E;0;306;A00012345;V123'; preg_match('/(?<=date)([\d]+);(.+);((?=A).+);(V.+)/', $str, $matches); var_dump($matches); --- Добавлено --- В песочнице
Возник дополнительный вопрос: 1. Переменная $str не принимает данные из базы данных $str = $dbc->query('SELECT str FROM table'); 2. как результат (preg_match) массива сохранить в БД?
PHP: var_dump($str); // что выводит? В любом случае, результат запроса нужно в цикле обрабатывать. Типа так: PHP: <?php while($dbc->query('SELECT str FROM table') as $item) { if(preg_match('/(?<=date)([\d]+);(.+);((?=A).+);(V.+)/', $str, $matches)) { // Тут запрос на добавлени или обновление в БД } } В чем конкретно проблема? Вы вообще PDO используете?
В самом MySQL есть функция substring_index() которой ты можешь вытащить подстроки прямо в запросе - без участия php. Код (SQL): INSERT INTO `newtable`(`date`, `map`, `key`, `v`) SELECT SUBSTRING_INDEX(`x`, ';', 1), SUBSTRING_INDEX(`x`, ';', 2), -- с map на самом деле немного хитрее, но суть надеюсь понятна SUBSTRING_INDEX(`x`, ';', 3), SUBSTRING_INDEX(`x`, ';', 4), FROM `oldtable` на всякий: склеивать строки в MySQL можно функциями CONCAT() и CONCAT_WS() https://dev.mysql.com/doc/refman/8.0/en/string-functions.html
На самом деле, там всё немного хитрее Первую и последнюю подстроку получить достаточно просто (* для последней - SUBSTRING_INDEX(`x`,';',-1)), с подстрокой `key` как бы тоже не очень сложно SUBSTRING_INDEX(SUBSTRING_INDEX(`x`, ';', -2), ';', 1). Ну, а для `map` варианты есть разные, но не все могут быть надёжные. В принципе, как вариант: Код (SQL): SELECT REPLACE(SUBSTRING_INDEX(`x`, ';', 1), 'date', ''), SUBSTRING(`x`, LOCATE(';', `x`)+1, LENGTH(`x`) - (LOCATE(';', `x`)+1) - LENGTH(SUBSTRING_INDEX(`x`, ';', -2))), SUBSTRING_INDEX(SUBSTRING_INDEX(`x`, ';', -2), ';', 1), SUBSTRING_INDEX(`x`, ';', -1) FROM `my_table`
Ответ интерпретатора PHP: Warning: preg_match() expects parameter 2 to be string т.е. переменная $str должна быть строкой использую PDO: try { $dbc = new PDO($db_source,$db_user,$db_pass); } catch (PDOException $e) { echo 'Can not connect to DB: ' . $e->getMessage(); }
PHP: <?php $arr = []; while($dbc->query('SELECT str FROM table') as $item) { $arr[] = $item; } print_r($arr); покажите что в массиве $arr
вместо while foreach: Array ( [0] => Array ( [log] => #D#300519;045518;5323.3395;N;06255.0152;E;0;14; 200;16;0.61;NA;NA;;A000000196C8;Type:3:TR,Idx:1:6284,FSD:3:300519,FST:3:045012,FCD:3:300519,FCT:3:045518,A:1:0,Vtag:1:000,Vrdr:1:000,Pump:1:1,Limit:1: 0,FV:2:00588.00,FP:1:000000000,TOT:1:0005984574,FL0:1:0,FV0:1:0,FT0:1:0,FD0:1:0,FL1:1:0,FV1:1:0,FT1:1:0,FD1:1:0,VID:1:0000,ODO:1:00000000 [0] => #D#300519;045518;5323.3395;N;06255.0152;E;0;14; 200;16;0.61;NA;NA;;A000000196C8;Type:3:TR,Idx:1:6284,FSD:3:300519,FST:3:045012,FCD:3:300519,FCT:3:045518,A:1:0,Vtag:1:000,Vrdr:1:000,Pump:1:1,Limit:1: 0,FV:2:00588.00,FP:1:000000000,TOT:1:0005984574,FL0:1:0,FV0:1:0,FT0:1:0,FD0:1:0,FL1:1:0,FV1:1:0,FT1:1:0,FD1:1:0,VID:1:0000,ODO:1:00000000 ) [1] => Array ( [log] => #D#300519;045518;5323.3395;N;06255.0152;E;0;14; 200;16;0.61;NA;NA;;A000000196C8;Type:3:TR,Idx:1:6284,FSD:3:300519,FST:3:045012,FCD:3:300519,FCT:3:045518,A:1:0,Vtag:1:000,Vrdr:1:000,Pump:1:1,Limit:1: 0,FV:2:00588.00,FP:1:000000000,TOT:1:0005984574,FL0:1:0,FV0:1:0,FT0:1:0,FD0:1:0,FL1:1:0,FV1:1:0,FT1:1:0,FD1:1:0,VID:1:0000,ODO:1:00000000 [0] => #D#300519;045518;5323.3395;N;06255.0152;E;0;14; 200;16;0.61;NA;NA;;A000000196C8;Type:3:TR,Idx:1:6284,FSD:3:300519,FST:3:045012,FCD:3:300519,FCT:3:045518,A:1:0,Vtag:1:000,Vrdr:1:000,Pump:1:1,Limit:1: 0,FV:2:00588.00,FP:1:000000000,TOT:1:0005984574,FL0:1:0,FV0:1:0,FT0:1:0,FD0:1:0,FL1:1:0,FV1:1:0,FT1:1:0,FD1:1:0,VID:1:0000,ODO:1:00000000 ) )
PHP: <?php while($dbc->query('SELECT str FROM table') as $item) { if(preg_match('/(?<=date)([\d]+);(.+);((?=A).+);(V.+)/', $item['log'], $matches)) { // Тут запрос на добавлени или обновление в БД } } --- Добавлено --- кстати регулярка работать не будет, вы вытягиваете не то что описали.
при работе с большими объемами данных пришлось увеличить max_execution_time. теперь нужно понять как экономить ресурсы при разработке web приложений.