求助:PHP正则匹配至符号最后出现位置的实现方案
嘿,这个坑我踩过!你之前的正则Data\s?=\s?{[^}]+};?失效的原因很简单——[^}]+会在碰到第一个}就立刻停止匹配,但你的b字段值里嵌套了多层JSON结构,里面全是},所以匹配到一半就被截断了。
要解决嵌套大括号的匹配问题,PHP正则支持递归匹配(平衡组),专门用来处理这种成对嵌套的结构。你可以用下面这个正则:
preg_match_all('/Data\s?=\s?{(?:[^{}]|(?R))*}/', $input, $matches);
正则拆解:
Data\s?=\s?:匹配"Data"、可选空格、等于号、可选空格,和你原来的逻辑一致{(?:[^{}]|(?R))*}:这是核心的平衡匹配部分:{:匹配最外层的左大括号(?:[^{}]|(?R))*:非捕获组,循环匹配两种内容:要么是非大括号的任意字符,要么是递归整个正则规则(也就是匹配嵌套的{...}结构)}:直到找到与最外层配对的右大括号才停止
完整代码示例:
$input = <<<EOT var Data = { 'a': 1, 'b': '{"a":[{"b":{"id":1}}]}' } var Data = { 'a': 2, 'b': '{"a":[{"b":{"id":2}}]}' }; // Some other text here that may have }; or }. Blahblah blah. // }; // } EOT; // 执行匹配 preg_match_all('/Data\s?=\s?{(?:[^{}]|(?R))*}/', $input, $matches); // 输出你想要的结果 foreach ($matches[0] as $result) { echo $result . "\n"; }
运行这段代码后,就能得到你需要的两个完整结果:
Data = { 'a': 1, 'b': '{"a":[{"b":{"id":1}}]}' } Data = { 'a': 2, 'b': '{"a":[{"b":{"id":2}}]}' }
如果你需要保留后面的分号(或者处理可选分号),可以把正则调整为:
preg_match_all('/Data\s?=\s?{(?:[^{}]|(?R))*};?/', $input, $matches);
另外提一句:如果你的字符串里有UTF-8字符,记得给正则加上u修饰符,避免乱码问题。
内容的提问来源于stack exchange,提问作者temuri
相关产品推荐
相关产品推荐

