如何使用 php 进入嵌套大括号?
例:
{{ text1 {{text2 text3 {{text4}} text5}} }}
应该输出
1- text1 {{text2 text3 {{text4}} text5}}
2- text2 text3 {{text4}} text5
3- text4
这需要跟踪括号的数量,并且无法使用正则表达式来完成。您必须为此创建自己的解析器逻辑。正则表达式不是解析器,抱歉。
这是另一个类似的问题,与我的回答相同
这是一个关于构建解析的SO(在Java中,但它应该翻译得足够好)
像Perl一样,PCRE可以将嵌套结构匹配到任意深度(仅受内存限制 - 见下文)。下面是一个经过测试的脚本:
正则表达式以匹配嵌套括号
<?php // test.php Rev:20120702_1100
$re_nested_double_bracket ='% # Rev:20120702_1100
# Match {{...{{...}}...}} structure with arbitrary nesting.
'{'{ # Opening literal double bracket.
( # $1: Contents of double brackets.
(?: # Group for contents alternatives.
[^{}]++ # Either one or more non-brackets,
| (?R) # or a nested bracket pair,
| '{ # or the start of opening bracket
(?!'{) # (if not a complete open bracket),
| '} # or the start of closing bracket.
(?!'}) # (if not a complete close bracket).
)* # Zero or more contents alternatives.
) # End $1: Contents of double brackets.
'}'} # Closing literal double bracket.
%x';
$results = array(); // Global array to receive results.
// Recursively called callback routine adds to $results array.
function _bracket_contents_callback($matches) {
global $results, $re_nested_double_bracket;
$results[] = $matches[1];
preg_replace_callback($re_nested_double_bracket,
'_bracket_contents_callback', $matches[1]);
return $matches[0]; // Don't modify string.
}
$input = file_get_contents('testdata.txt');
preg_replace_callback($re_nested_double_bracket,
'_bracket_contents_callback', $input);
$count = count($results);
printf("There were %d matches found.'n", $count);
for ($i = 0; $i < $count; ++$i) {
printf(" Match[%d]: %s'n", $i + 1, $results[$i]);
}
?>
当针对原始帖子中的测试数据运行时,以下是正则表达式匹配的内容:
示例输出:
There were 3 matches found.
Match[1]: text1 {{text2 text3 {{text4}} text5}}
Match[2]: text2 text3 {{text4}} text5
Match[3]: text4
请注意,此正则表达式匹配最外层的可能嵌套括号集,并将括号之间的内容捕获到组中$1
。该脚本利用 preg_replace_callback()
函数递归匹配并将嵌套括号内容添加到结果数组中。
"任意深度" 请注意,此解决方案将嵌套括号与任何"任意深度"匹配,但始终受到系统内存、可执行堆栈大小和 PHP pcre.backtrack_limit
、pcre.recursion_limit
和memory_limit
配置变量的限制。请注意,如果主题字符串对于给定主机系统来说太大和/或嵌套太深,则此正则表达式解决方案肯定有可能失败。PHP/PCRE 库甚至可能导致正在运行的可执行文件生成堆栈溢出、分段错误和程序崩溃!请参阅我对相关问题的回答,深入了解如何以及为什么会发生这种情况(以及如何避免它并优雅地处理此类错误):preg_match函数中的正则表达式返回浏览器错误和PHP 正则表达式:这段代码有什么问题吗?
注意:这个问题(和我的答案)几乎与:使用正则表达式解析专有标签语法 - 如何检测嵌套标签?,但在这个答案中,提出了一个更完整的解决方案,它递归匹配并存储所有嵌套括号内容。
我已经找到了我正在寻找的答案并将其放在这里,以便每个人都可以使用它。它确实非常简单,仅在一行中:
$text1=preg_replace("/'{'{(([^{}]*|(?R))*)'}'}/",'',$text1);
它将搜索并将所有{{text}}替换为您想要的任何内容。您还可以使用 preg_match_all 将它们全部放入数组中。