How to json_decode invalid JSON with apostrophe instead of quotation mark

json, php

Solution

Here's an alternative solution to this problem:

function fixJSON($json) {
    $regex = <<<'REGEX'
~
    "[^"\\]*(?:\\.|[^"\\]*)*"
    (*SKIP)(*F)
  | '([^'\\]*(?:\\.|[^'\\]*)*)'
~x
REGEX;

    return preg_replace_callback($regex, function($matches) {
        return '"' . preg_replace('~\\\\.(*SKIP)(*F)|"~', '\\"', $matches[1]) . '"';
    }, $json);
}

This approach is more robust than h2ooooooo's function in two respects:

- It preserves double quotes occurring in a single quoted string, by applying additional escaping to them. h2o's variant will replace them with double quotes instead, thus changing the value of the string.

- It will properly handle escaped double quotes `\"`, for which h2o's version seems to go into an infinite loop.

Test:

$brokenJSON = <<<'JSON'
['foo', {"bar": "hel'lo", "foo": 'ba"r ba\"z', "baz": "wor\"ld ' test"}]
JSON;

$fixedJSON = fixJSON($brokenJSON);
$decoded = json_decode($fixedJSON);

var_dump($fixedJSON);
print_r($decoded);

Output:

string(74) "["foo", {"bar": "hel'lo", "foo": "ba\"r ba\"z", "baz": "wor\"ld ' test"}]"
Array
(
    [0] => foo
    [1] => stdClass Object
        (
            [bar] => hel'lo
            [foo] => ba"r ba"z
            [baz] => wor"ld ' test
        )
)

Problem

Sample code: ``` <?php $json = "['foo', 'bar']"; var_dump( json_decode($json) ); ``` It works with PHP 5.5.3 but it fails for lower PHP's versions It works on my machine with PHP 5.5.3 but it fails everywhere else. I know it is incorrect JSON but my webservice gives me JSON with `'` symbols together with `"` ``` ['foo', "bar", {'test': "crazy \"markup\""}] ``` Sandbox How to parse JSON data with apostrophes in PHP 5.3? Obviously original JSON I want to parse is more complex. (I can't upgrade my PHP on production server neither get proper JSON from webservice)

Original source

Related problems