我想在两个冰壶括号内首次出现的角色匹配,但忽略其中的角色。
{{some text here {{nested text here}} another text {{another nested text here}} final text}}
所以结果必须是
some text here {{nested text here}} another text {{another nested text here}} final text
但是这次搜索
preg_match_all("^\{{(.*?)\}}^", $string, $results);
给了我第一对括号内的那些:
$results[0][0] = nested text here
$results[0][1] = another nested text here
有没有办法用preg_match_all来实现这个目标?
答案 0 :(得分:3)
嵌套结构经常会导致正则表达式出现问题(因为它们使语言匹配比常规更复杂)。 PCRE是其中一个引擎,它允许匹配它们,因为它支持递归。如果您的双括号内没有单个花括号,则可以使用此模式:
'/\{\{[^{}]*(?:(?R)[^{}]*)*\}\}/'
(?R)
将整个模式再次嵌入其中。
我不确定PCRE的优化程度,但你可以通过重复possessive来帮助我。这抑制了回溯,这在这里是不必要的,因为所有连续的重复是相互排斥的:
'/\{\{[^{}]*+(?:(?R)[^{}]*+)*+ \}\}/'
如果你允许使用单个括号,你可以做一些类似于前瞻的东西,但这已经说明为什么正则表达式不是真正用于嵌套结构(即使引擎支持它):
'/\{\{(?:(?!\{\{|\}\}).)*(?:(?R)(?:(?!\{\{|\}\}).)*)*\}\}/'
现在我们允许重复任何字符,而不是非{}
个字符,除非它标记{{
或}}
的开头。再次,使它占有欲可能是一个好主意:
'/\{\{(?:(?!\{\{|\}\}).)*+(?:(?R)(?:(?!\{\{|\}\}).)*+)*+\}\}/'