如何用撇号而不是引号json_decode无效的JSON [英] How to json_decode invalid JSON with apostrophe instead of quotation mark

查看:85
本文介绍了如何用撇号而不是引号json_decode无效的JSON的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

示例代码:

<?php

$json = "['foo', 'bar']";

var_dump( json_decode($json) );

它可与 PHP 5.5.3 一起使用,但对于较低版本的PHP则无法使用

它可以在我的装有PHP 5.5.3的计算机上使用,但在其他地方都无法使用.

我知道它是不正确的JSON,但是我的网络服务为我提供了带有'符号和"

的JSON.

['foo', "bar", {'test': "crazy \"markup\""}]

沙盒

如何在PHP 5.3中使用撇号解析JSON数据? 我想解析的原始JSON显然更复杂.

(我无法在生产服务器上升级PHP,也无法从Web服务获取正确的JSON)

解决方案

以下是此问题的替代解决方案:

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

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

此方法在两个方面比h2ooooooo的功能更健壮:

  • 通过对单引号引起来的双引号进行额外的转义,可以保留双引号. h2o的变体会将其替换为双引号,从而更改了字符串的值.
  • 它将正确处理转义的双引号\",为此,h2o的版本似乎陷入了无限循环.

测试:

$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);

输出:

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
        )
)

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)

解决方案

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
        )
)

这篇关于如何用撇号而不是引号json_decode无效的JSON的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆