PHP:JSON中的正则表达式导致json_decode问题?

时间:2019-01-19 02:00:51

标签: php json regex escaping

我的JSON中有一些正则表达式,当我在在线JSON验证器上测试JSON时,这似乎不是问题。但是,当我使用该JSON字符串并尝试在PHP中json_decode()时,会得到 JSON_ERROR_SYNTAX

任何想法为何?而我该如何解决呢?

示例代码:

<?php

$json = <<<EOD
{
  "regex": [
    "Hello\s+World"
  ]
}
EOD;

json_decode($json);

switch (json_last_error()) {
    case JSON_ERROR_NONE:
        echo ' - No errors';
    break;
    case JSON_ERROR_DEPTH:
        echo ' - Maximum stack depth exceeded';
    break;
    case JSON_ERROR_STATE_MISMATCH:
        echo ' - Underflow or the modes mismatch';
    break;
    case JSON_ERROR_CTRL_CHAR:
        echo ' - Unexpected control character found';
    break;
    case JSON_ERROR_SYNTAX:
        echo ' - Syntax error, malformed JSON';
    break;
    case JSON_ERROR_UTF8:
        echo ' - Malformed UTF-8 characters, possibly incorrectly encoded';
    break;
    default:
        echo ' - Unknown error';
    break;
}

问题出在\s中。将其更改为\\s并没有帮助。

3 个答案:

答案 0 :(得分:7)

在PHP中编写"\s"时,文字字符串为\s,因为\s不是有效的转义序列。

在PHP中编写"\\s"时,文字字符串为\s,因为\\ 是有效的转义序列。

另一方面,JSON将针对无效的转义序列抛出错误,这是您的问题。

解决方案: 请勿手动编写JSON。

$json = json_encode(['regex'=> ['Hello\s+World']]);

输出:{"regex":["Hello\\s+World"]} [注:文字字符串,有效的JSON]

糟糕的解决方案,其严重性超出其价值,并且很可能会导致一系列问题: "Hello\\\s+World"欢迎逃避现实。

答案 1 :(得分:2)

您的字符串"Hello\s+World"必须像"Hello\\\s+World"那样转义。第一个转义\用于转义第二个转义\,用于转义\s

然后,如果要在输出中包含数组,则必须将assoc = true设置为json_decode()函数的第二个参数。

documentation 中了解有关json_decode()功能的更多信息。

解决方案

请参阅我的代码中的 DEMO

<?php
$json = '{"regex":["Hello\\\s+World"]}';

$obj1 = json_decode($json);
echo $obj1->regex[0]."<br>";

$obj2 = json_decode($json, true); //When assoc == TRUE, returned objects will be converted into associative arrays.
echo $obj2["regex"][0];
?>

如何转义所有JSON控制字符:

答案 2 :(得分:1)

由于潜在的正则表达式和双重转义问题,您没有得到期望的字符串文字。

这适用于任何正则表达式:

$regex1 = <<<EOD
Hello\s+World
EOD;

$obj = new stdClass();
$obj->regex = array();
$obj->regex[] = $regex1;

$json = json_encode($obj);

$decoded = json_decode($json);

var_dump($decoded->regex[0]);

输出

string(13) "Hello\s+World"