是否可以编写与未出现次数的嵌套模式匹配的正则表达式?例如,当外括号内嵌有未知数量的打开/关闭括号时,正则表达式是否可以匹配开括号和右括号?
例如:
public MyMethod()
{
if (test)
{
// More { }
}
// More { }
} // End
Run Code Online (Sandbox Code Playgroud)
应该匹配:
{
if (test)
{
// More { }
}
// More { }
}
Run Code Online (Sandbox Code Playgroud) 编辑:我选择了ridgerunner的答案,因为它包含解决问题所需的信息.但我也想为特定问题添加一个完全充实的解决方案,以防其他人想要完全理解这个例子.你会发现它在下面的某个地方.
这个问题是关于澄清php的正则表达式引擎的递归表达式的行为.(如果你想法如何在不使用递归的php正则表达式的情况下正确匹配下面的字符串,这非常酷,但这不是问题.)
a(?:(?R)|a?)a
Run Code Online (Sandbox Code Playgroud)
这是一个简单的表达式,旨在匹配字符"a"或没有任何内容,嵌套在字符"a"的一个或多个嵌套中.例如,aa,aaa,aaaa,aaaaa.您不需要为此使用递归:
aa*a
Run Code Online (Sandbox Code Playgroud)
会很棒.但重点是使用递归.
以下是您可以运行的一段代码来测试我的失败模式:
<?php
$tries=array('a','aa','aaa','aaaa','aaaaa','aaaaaa');
$regex='#a(?:(?R)|a?)a#';
foreach ($tries as $try) {
echo $try." : ";
if (preg_match($regex,$try,$hit)) echo $hit[0]."<br />";
else echo 'no match<br />';
}
?>
Run Code Online (Sandbox Code Playgroud)
在该模式中,两个"a"构成交替.在交替中,我们要么匹配整个模式的递归(两个"a"构成交替),要么匹配字符"a",可选地为空.
在我看来,对于"aaaa",这应该与"aaaa"相匹配.
但这是输出:
a : no match
aa : aa
aaa : aaa
aaaa : aaa
aaaaa : aaaaa
aaaaaa : aaa
Run Code Online (Sandbox Code Playgroud)
有人能解释第三和第五行输出的情况吗?我试过追踪我想象引擎必须采取的路径,但我必须想象它是错的.为什么引擎返回"aaa"作为"aaaa"的匹配?是什么让它如此渴望?我必须以错误的顺序想象匹配的树.
我意识到了
#(?:a|a(?R)a)*#
Run Code Online (Sandbox Code Playgroud)
有点作品,但我的问题是为什么其他模式没有.
谢谢堆!