我正在尝试编写一个与嵌套括号匹配的正则表达式,例如:
"(((text(text))))(text()()text)(casual(characters(#$%^^&&#^%#@!&**&#^*!@#^**_)))"
像这样的字符串应该被匹配,因为所有嵌套的括号都被关闭,而不是:
"(((text)))(text)(casualChars*#(!&#*(!))"
不应该,或者更好,应该至少匹配第一个“(((text)))(text)”部分。
实际上,我的正则表达式是:
$regex = '/( ( (\() ([^[]*?) (?R)? (\)) ){0,}) /x';
但它并没有像我预期的那样正常工作。如何解决这个问题?我哪里错了?谢谢!
该模式的工作原理:
$pattern = '~ \( (?: [^()]+ | (?R) )*+ \) ~x';
括号内的内容简单描述一下:
“所有不是括号或递归(=其他括号)” x 0 次或多次
如果要捕获括号内的所有子字符串,则必须将此模式放入前瞻中以获得所有重叠结果:
$pattern = '~(?= ( \( (?: [^()]+ | (?1) )*+ \) ) )~x';
preg_match_all($pattern, $subject, $matches);
print_r($matches[1]);
请注意,我添加了一个捕获组并替换了(?R)
by (?1)
:
(?R) -> refers to the whole pattern (You can write (?0) too)
(?1) -> refers to the first capturing group
这个前瞻技巧是什么?
前向(或后向)内的子模式不匹配任何内容,它只是一个断言(测试)。因此,它允许多次检查相同的子字符串。
如果显示整个模式结果(print_r($matches[0]);
),您将看到所有结果都是空字符串。获取由前瞻内的子模式找到的子字符串的唯一方法是将子模式包含在捕获组中。
注意:递归子模式可以这样改进:
\( [^()]*+ (?: (?R) [^()]* )*+ \)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)