繁体   English   中英

PHP/正则表达式:在字符串中解析 JSON

[英]PHP/Regex: Parse JSON in string

我试图在字符串中找到简单的键值对,以 JSON 对象的形式给出,同时使用 preg_replace_callback()。

不幸的是,给定的值可以是字符串、数字、boolean、null、数组以及最糟糕的对象类型。 我自己解决此问题的尝试导致选择不完整或过度选择多个 JSON 事件作为一个。

这是我尝试过的事情:

String:
text text {"key":{"key":"value"}} text

Regex:
\{"(.+?)"\:(.+?)\}

Match:
{"key":"value"

上图:这忽略了内部 } 括号

String:
text text {"key":{"key":"value"}} text

Regex:
\{"(.+?)"\:(.+)\}

Match:
{"key":"value"}

上图:这(理论上)会起作用,但是当出现多个 JSON 时,我得到:

{"key":"value"}} {"key":{"key":"value"}

下一次尝试:

String:
text text {"key":{"key":"value"}} {"key":{"key":"value"}} text

Regex:
\{"(.+?)"\:(?:(\{(?:.+?)\})|(?:")?(.+?)(?:")?)\}

Match:
{"key":"value"}

上图:再一次,这在理论上是可行的。 但是,例如,使用以下字符串时:

text text {"key":{"key":{"key":"value"}}} text

结果是……

{"key":{"key":"value"}

缺少一个括号

PCRE 支持这种嵌套结构的递归匹配。 这是一个演示:

$data = 'text text 
  {"key":{"key":"value{1}","key2":false}} 
  {"key":{"key":"value2"}} 
  {"key":{"key":{"key":"value3"}}} text';

$pattern = '(
    \{ # JSON object start
        ( 
            \s*
            "[^"]+"                  # key
            \s*:\s*                  # colon
            (
                                     # value
                (?: 
                    "[^"]+" |        # string
                    \d+(?:\.\d+)? |  # number
                    true |
                    false |
                    null
                ) | 
                (?R)                 # pattern recursion
            )
            \s*
            ,?                       # comma
        )* 
    \} # JSON object end
)x';
preg_replace_callback(
    $pattern,
    function ($match) {
        var_dump(json_decode($match[0]));
    },
    $data
);

由于使用preg_replace_callback()的额外要求并且提前不知道 json 对象的深度,也许这是另一种可能的方法( 有关{1,}的更多信息here ):

<?php

// ref: https://stackoverflow.com/q/66379119/1167750
$str = 'text text {"key":{"key":"value1"}} {"key":{"key":"value2"}} {"key":{"key":{"key":"value3"}}} text';

function callback($array) {
    // Your function here...
    print_r($array);
    echo "Found:\n";
    echo "{$array[0]}\n";
}


preg_replace_callback('/\{"(.+?)"\:(.+?)\}{1,}/', 'callback', $str);

?>

Output(PHP 7.3.19):

$ php q18.php
Array
(
    [0] => {"key":{"key":"value1"}}
    [1] => key
    [2] => {"key":"value1"
)
Found:
{"key":{"key":"value1"}}
Array
(
    [0] => {"key":{"key":"value2"}}
    [1] => key
    [2] => {"key":"value2"
)
Found:
{"key":{"key":"value2"}}
Array
(
    [0] => {"key":{"key":{"key":"value3"}}}
    [1] => key
    [2] => {"key":{"key":"value3"
)
Found:
{"key":{"key":{"key":"value3"}}}

以前的想法:

这样的事情对您的用例有帮助吗?

<?php

// ref: https://stackoverflow.com/q/66379119/1167750
$str = 'text text {"key":{"key":"value1"}} {"key":{"key":"value2"}} {"key":{"key":{"key":"value3"}}} text';

preg_match_all('/\{"(.+?)"\:(.+?)\}{1,3}/', $str, $matches);

print_r($matches);

echo "Found:\n";
print_r($matches[0]);

?>

Output(PHP 7.3.19):

$ php q18.php
Array
(
    [0] => Array
        (
            [0] => {"key":{"key":"value1"}}
            [1] => {"key":{"key":"value2"}}
            [2] => {"key":{"key":{"key":"value3"}}}
        )

    [1] => Array
        (
            [0] => key
            [1] => key
            [2] => key
        )

    [2] => Array
        (
            [0] => {"key":"value1"
            [1] => {"key":"value2"
            [2] => {"key":{"key":"value3"
        )

)
Found:
Array
(
    [0] => {"key":{"key":"value1"}}
    [1] => {"key":{"key":"value2"}}
    [2] => {"key":{"key":{"key":"value3"}}}
)

如果您提前知道这些嵌套结构可能的最大深度,您可以提前将{1,3}部分调整为不同的设置。 例如: {1,4}{1,5}等。有关该部分的更多信息可以 在此处的文档中找到。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM