[英]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.