I've a string that I want to convert to a valid JSON and then json_decode it. Here's what the string looks like:
[
['test', 'lol'],
['test2', 'lol2']
]
[
['test32', 'loDl'],
['test32', 'loDl2']
]
[
['tes23t', 'loDEl'],
['testDE2', 'lolDE2']
]
I want to get only the data between each
[
]
so the result might to be:
['test', 'lol'],
['test2', 'lol2'],
['test32', 'loDl'],
['test32', 'loDl2'],
['tes23t', 'loDEl'],
['testDE2', 'lolDE2']
so I think that I need to use regex
and preg_split
, here's what I did:
$jsons = preg_split('/\]\s*(?=\[)/', $data, null);
$jsond = "";
foreach ($jsons as $json) {
$json .= "";
$jsond .= $json;
}
return $jsond;
but It's not working, I still can't have the data beetween each [ ]
How can I do that ?
Thanks in advance
PS: here's the real full string https://paste.ee/r/RN7rK
The string you pointed to has valid JSON on each line. However, all the lines together do not represent one valid JSON.
I propose to manipulate the data in a minimal way to make the whole text JSON with a simple regular expression. If the original data is in $data , then create the JSON as follows:
$json = preg_replace('/(\])\](\R)\[/', '$1,$2', $data);
This will remove both the closing bracket at the end of a line, and the opening one at the start of the next line. Instead a comma is inserted. The result will be valid JSON, as the opening bracket right at the start now matches with the very final closing bracket.
I took some representative text from your data:
$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"]]';
It just has two lines, to limit the data a bit. Now the above code produces this result, pretty printed:
[
[
"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"
]
]
If you have a lot of data and have to preserve memory, you can use something like this:
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;
}
This isn't a fast method but the memory footprint is very low since the file is never fully loaded in memory.
Note I don't know what you want to do with your data and if converting them to JSON is a good idea (JSON is useful to share data between apps, but if you want something you can easily and efficiently querying, it's better to use a database.)
This is also possible solution:
$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);
?>
will output:
['test', 'lol'],['test2', 'lol2'],['test32', 'loDl'],['test32', 'loDl2'],['tes23t', 'loDEl'],['testDE2', 'lolDE2']
Is this what you want?
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.