Reputation: 14869
I am trying to iterate a data set in My SQL, and automatically update json strings which have an object member set as Int instead of String. I am just looking for the quickest and simplest way, so I've gotten into regex.
My json should look like this:
{
"nodeFrom":"0624a5d0-2cca-4a21-88da-3c7969e25754",
"nodeTo":"db651b3a-3ccd-4014-9c74-33637b2128d3",
"index":"1",
"order":"cr"
}
However, due to earlier assumptions (the mother of all...) some in the database have:
{
"nodeFrom":"0624a5d0-2cca-4a21-88da-3c7969e25754",
"nodeTo":"db651b3a-3ccd-4014-9c74-33637b2128d3",
"index":1,
"order":"cr"
}
Which creates issues in C++ apps accessing this data, due to non-string assertions.
I wrote the following (I am ommiting the mysqli code) which detects where the problem is:
while ( $row = $result->fetch_array(MYSQLI_ASSOC) )
{
$uuid = $row['uuid'];
$json = $row["json"];
$pattern = '/"index":\d+/';
$matches = array();
$count = preg_match_all( $pattern, $json, $matches );
// NOTE: We need to use preg_replace
if ( $count > 0 )
printf ( "found %s json ints in uuid %s \r\n", $count, $uuid );
Now, I need to use preg_match_replace in order to replace all occurances where this pattern is detected, by adding the extra quotes to the digit. All examples I have seen, simply replace one pattern for another, yet in this case, I want the digit, to be replaced by a digit with quotes.
Upvotes: 1
Views: 517
Reputation: 808
As an alternative to a regex, you could also decode the JSON string, modify, and encode back to JSON.
$json = <<<EOD
{
"nodeFrom":"0624a5d0-2cca-4a21-88da-3c7969e25754",
"nodeTo":"db651b3a-3ccd-4014-9c74-33637b2128d3",
"index":1,
"order":"cr"
}
EOD;
$object = json_decode($json, true);
$object["index"] = strval($object["index"]);
$json = json_encode($object, JSON_PRETTY_PRINT);
echo $json;
Output:
{
"nodeFrom": "0624a5d0-2cca-4a21-88da-3c7969e25754",
"nodeTo": "db651b3a-3ccd-4014-9c74-33637b2128d3",
"index": "1",
"order": "cr"
}
This could also be done recursively on any arbitrary JSON string:
$json = <<<EOD
[
{
"nodeFrom":"0624a5d0-2cca-4a21-88da-3c7969e25754",
"nodeTo":"db651b3a-3ccd-4014-9c74-33637b2128d3",
"index":1,
"order":"cr"
},
{
"otherObject":2,
"list": [
12,
32
]
}
]
EOD;
$arrays = json_decode($json, true);
array_walk_recursive($arrays, function(&$value){
if (! is_string($value) && ! is_array($value))
{
$value = strval($value);
}
});
echo json_encode($arrays, JSON_PRETTY_PRINT);
Output:
[
{
"nodeFrom": "0624a5d0-2cca-4a21-88da-3c7969e25754",
"nodeTo": "db651b3a-3ccd-4014-9c74-33637b2128d3",
"index": "1",
"order": "cr"
},
{
"otherObject": "2",
"list": [
"12",
"32"
]
}
]
Upvotes: 2
Reputation: 781592
Use a capture group in the regexp and back-reference in the replacement:
$json = preg_replace('/"index":(\d+)/', '"index":"$1"', $json);
Upvotes: 1