У меня есть строка, которую я хочу преобразовать в действительный JSON, а затем json_decode. Вот как выглядит строка:
[ ['test', 'lol'], ['test2', 'lol2'] ] [ ['test32', 'loDl'], ['test32', 'loDl2'] ] [ ['tes23t', 'loDEl'], ['testDE2', 'lolDE2'] ]
Я хочу получить только данные между
[ ]
поэтому результат может быть:
['test', 'lol'], ['test2', 'lol2'], ['test32', 'loDl'], ['test32', 'loDl2'], ['tes23t', 'loDEl'], ['testDE2', 'lolDE2']
поэтому я думаю, что мне нужно использовать regex
и preg_split
, вот что я сделал:
$jsons = preg_split('/\]\s*(?=\[)/', $data, null); $jsond = ""; foreach ($jsons as $json) { $json .= ""; $jsond .= $json; } return $jsond;
но он не работает, я все еще не могу иметь данные между каждым [ ]
Как я могу это сделать ?
заранее спасибо
PS: вот настоящая полная строка https://paste.ee/r/RN7rK
Строка, на которую вы указали, имеет действительную JSON в каждой строке. Однако все строки вместе не представляют собой один действительный JSON.
Я предлагаю манипулировать данными в минимальном порядке, чтобы весь текст JSON с простым регулярным выражением. Если исходные данные находятся в $ data , тогда создайте JSON следующим образом:
$json = preg_replace('/(\])\](\R)\[/', '$1,$2', $data);
Это приведет к удалению как закрывающей скобки в конце строки, так и открытию в начале следующей строки. Вместо этого вводится запятая. Результат будет действителен JSON, так как открывающая скобка прямо на старте теперь совпадает с самой последней закрывающей скобкой.
Я взял некоторые данные из ваших данных:
$data = '[["s","13","shelves_norja","49500","0","1","1","#ffffff,#F7EBBC","Beige Bookcase","For nic naks and books.","","5","true","-1","false","","1","true","0","0","0","false"],["s","117","table_plasto_round*9","45508","0","2","2","#ffffff,#533e10","Round Dining Table","Hip plastic furniture","","-1","false","-1","false","","1","false","0","0","0","false"]] [["s","118","table_plasto_square*9","45508","0","1","1","#ffffff,#533e10","Occasional Table","Hip plastic furniture","","-1","false","-1","false","","1","false","0","0","0","false"],["s","119","chair_plasto*9","45508","0","1","1","#ffffff,#533e10,#ffffff,#533e10","Chair","Hip plastic furniture","","-1","false","-1","false","","1","false","0","1","0","false"],["s","120","carpet_standard*6","48082","0","3","5","#777777","Floor Rug","Available in a variety of colors","","105","true","-1","false","","1","true","1","0","0","false"],["s","121","chair_plasty*1","45508","0","1","1","#ffffff,#8EB5D1,#ffffff,#8EB5D1","Plastic Pod Chair","Hip plastic furniture","","-1","false","-1","false","","1","false","0","1","0","false"]]';
Он просто имеет две линии, чтобы немного ограничить данные. Теперь приведенный выше код производит этот результат, довольно печатный:
[ [ "s", "13", "shelves_norja", "49500", "0", "1", "1", "#ffffff,#F7EBBC", "Beige Bookcase", "For nic naks and books.", "", "5", "true", "-1", "false", "", "1", "true", "0", "0", "0", "false" ], [ "s", "117", "table_plasto_round*9", "45508", "0", "2", "2", "#ffffff,#533e10", "Round Dining Table", "Hip plastic furniture", "", "-1", "false", "-1", "false", "", "1", "false", "0", "0", "0", "false" ], [ "s", "118", "table_plasto_square*9", "45508", "0", "1", "1", "#ffffff,#533e10", "Occasional Table", "Hip plastic furniture", "", "-1", "false", "-1", "false", "", "1", "false", "0", "0", "0", "false" ], [ "s", "119", "chair_plasto*9", "45508", "0", "1", "1", "#ffffff,#533e10,#ffffff,#533e10", "Chair", "Hip plastic furniture", "", "-1", "false", "-1", "false", "", "1", "false", "0", "1", "0", "false" ], [ "s", "120", "carpet_standard*6", "48082", "0", "3", "5", "#777777", "Floor Rug", "Available in a variety of colors", "", "105", "true", "-1", "false", "", "1", "true", "1", "0", "0", "false" ], [ "s", "121", "chair_plasty*1", "45508", "0", "1", "1", "#ffffff,#8EB5D1,#ffffff,#8EB5D1", "Plastic Pod Chair", "Hip plastic furniture", "", "-1", "false", "-1", "false", "", "1", "false", "0", "1", "0", "false" ] ]
Если у вас много данных и вы должны сохранять память, вы можете использовать что-то вроде этого:
function genArrayFromFHandler($fh) { $state = 0; // (1: main brackets, 2: nested brackets, 3: quotes) while(!feof($fh)) { $c = fgetc($fh); switch($c): case '[': if ($state) $array = []; $state++; break; case ']': if ($state == 2) yield $array; $state--; break; case '"': if ($state == 2) { $state++; $item = ''; } else { $state--; $array[] = $item; } break; default: if ($state == 3) $item .= $c; endswitch; } } try { $fh = fopen('yourfile.txt', 'r');// or die ('error opening file'); if (!$fh) throw new Exception('File open failed.'); foreach (genArrayFromFHandler($fh) as $arr) { // do all what you need with the array here print_r($arr); } fclose($fh); } catch (Exception $e) { echo $e->getMessage() . PHP_EOL; }
Это не быстрый метод, но область памяти очень низкая, так как файл никогда полностью не загружается в память.
Примечание. Я не знаю, что вы хотите делать с вашими данными, и если преобразование их в JSON – хорошая идея (JSON полезен для обмена данными между приложениями, но если вы хотите что-то, что вы можете легко и эффективно запросить, лучше использовать базы данных.)
Это также возможное решение:
$data = preg_replace('/\s+/', '', $data); $data = str_replace("[[", "[", $data); $jsons = str_replace("]]", "]", $data);
echo $ jsons
['test','lol'],['test2','lol2']['test32','loDl'],['test32','loDl2']['tes23t','loDEl'],['testDE2','lolDE2']
<?php $data = "[ ['test', 'lol'], ['test2', 'lol2'] ] [ ['test32', 'loDl'], ['test32', 'loDl2'] ] [ ['tes23t', 'loDEl'], ['testDE2', 'lolDE2'] ]"; $matches = array(); preg_match_all('/\[(.*?)\]/', $data, $matches); $json = ''; foreach ($matches[0] as &$val) { $json .= $val.','; } $json = substr($json, 0, strlen($json)-1); ?>
выведет:
['test', 'lol'],['test2', 'lol2'],['test32', 'loDl'],['test32', 'loDl2'],['tes23t', 'loDEl'],['testDE2', 'lolDE2']
Это то, что вы хотите?