I have a string like this :
{
"XXX" "XXX"
"XXX" "XXX"
"XXX"
{
"XXX" "XXX"
"XXX" "XXX"
"XXX"
{
"XXX" "XXX"
}
"XXX"
{
"XXX" "XXX"
"XXX" "XXX"
"XXX" "XXX"
"XXX" "XXX"
"XXX" "XXX"
"XXX" "XXX"
"XXX" "XXX"
}
"XXX" "XXX"
}
"XXX"
{
"XXX" "XXX"
"XXX"
{
"XXX" "XXX"
}
"XXX"
{
"XXX" "XXX"
"XXX" "XXX"
"XXX" "XXX"
"XXX" "XXX"
"XXX" "XXX"
"XXX" "XXX"
"XXX" "XXX"
}
"XXX" "XXX"
}
"XXX"
{
"XXX" "XXX"
"XXX"
{
"XXX" "XXX"
}
"XXX"
{
"XXX" "XXX"
"XXX" "XXX"
"XXX" "XXX"
"XXX" "XXX"
"XXX" "XXX"
"XXX" "XXX"
}
"XXX" "XXX"
}
"XXX"
{
"XXX" "XXX"
"XXX"
{
"XXX" "XXX"
"XXX" "XXX"
"XXX" "XXX"
"XXX" "XXX"
"XXX" "XXX"
}
"XXX" "XXX"
}
"XXX"
{
"XXX"
{
"XXX" "XXX"
}
"XXX"
{
"XXX" "XXX"
"XXX" ""
}
"XXX"
{
"XXX" "XXX"
"XXX" ""
}
"XXX"
{
"XXX" "XXX"
"XXX" ""
}
"XXX"
{
"XXX" "XXX"
"XXX" ""
}
"XXX"
{
"XXX" "XXX"
"XXX" ""
}
"XXX"
{
"XXX" "XXX"
"XXX" ""
}
}
}
It looks like JSON, but it isn't : it's lacking all the commas (',') and all the colons (":"). I'm trying to find a way to parse it and turn into a valid JSON string.
My guess is to use the tabulations and the line breaks to find my way in the string, but so far I wasn't able to convert it to valid JSON.
I came up with this, which works but I believe is not very efficient or fail safe :
$e = explode( "
", $string );
foreach( $e as $k => $l ) {
$next = str_replace( "\t", '', $e[ $k + 1 ] );
$isParam = strstr( $l, "\"\t\t\"" );
$currentClean = str_replace( "\t", '', $l );
if ( $isParam )
$e[ $k ] = str_replace( "\"\t\t\"", '":"', $l );
if ( $isParam && $next != '}' )
$e[ $k ] .= ',';
if ( $currentClean == '}' && $next != '}' && $next )
$e[ $k ] .= ',';
if ( preg_match( '#^"(.*)"$#', $currentClean ) && !$isParam )
$e[ $k ] .= ':';
}
$json = implode("
", $e);
How to improve this ?
The problem is that you have several replaces at hand...so my answer comes with several calls (i try with all the text, it doesn´t need to be separated each line, just enter the full text).
//For the ":" before "}" and keys
$alltext = preg_replace("/(\"\w+\")\s+(\{|(\"\w*\"))/", "$1:$2", $alltext);
//For "," at the ends of the values:keys
$alltext = preg_replace("/(\"\w*\":\"\w*\")(?!\s+(\}|\{))/", "$1$2,", $alltext);
//For the "," at the end of each "}" that has a value after
$alltext = preg_replace("/(\})(\s+\")/", "$1,$2", $alltext);
PD: Dont know what your values are so thats why I left the \w+ in the answer. Let me know if it was helpful.
PD2:You can try it at phpliveregex
Not completely perfect but a really good start:
// Replace '"xxx" "xxx"' by '"xxx": "xxx",'
$string = preg_replace('/("[^"]+")\s+("[^"]*")/','$1: $2,',$string);
// Replace '} "xxx" {' with "} "xxx": {", accept "}" and "{" for start/end
$string = preg_replace('/([{}])(\s+)("[^"]+")\s+([{}])/','$1$2$3:$4',$string);
// Replace ", {" by " {"
$string = preg_replace('/,(\s*[}{])/','$1',$string);
echo $string;
Problem: There is a ,
placed after each match by first regex. Should not be the case for the last value in a list of values as here:
...
"XXX":{
"XXX": "XXX",
"XXX": "", <-- Wrong!
}
...
Working code example can be found at http://sandbox.onlinephpfunctions.com/code/36f618bbeaaa861a88b873144e25232c5ba2c8e1