正则表达式,跳过嵌套对

问题描述:

以我自己的标记语言,我有一个引用标记>>which use these characters to make a blockquote<<正则表达式,跳过嵌套对

>>(1) 
start1 
    >>(2)quote 2!<<(3) 
<<(4) 

我想匹配只有最外层标签,这样的:当有一个嵌套块引用问题开始

<blockquote> 
start1 
    >>quote 2!<< 
</blockquote> 

如果我尝试一个简单的ungreedy正则表达式/>>(.+?)<</,(1)和(3)将匹配并且(2)和(4)将不会匹配。如果我使它不合理/>>(.+)>>/(1)和(4)将成功匹配(并通过递归调用函数,我可以匹配(2)和(3)),但它不会工作,当我将有两个块在同一段文字:

>>(A)quote1<<(B) 

>>(C)quote2<<(D) 

贪婪一个将匹配(A)与(d),留下(B)和(C)单独。我想我必须以某种方式让它“不明朗”,但只有当内部没有其他对时,才会超出我的技能。有没有办法让它正常工作?所以(1)匹配(4),(A)匹配(B)和(C)匹配(D)?如果你能想到非正则表达式的解决方案(但不是解析器),那么它对我来说也是足够好的。我不问如何做(2)匹配(3),如何成功跳过它们(或任何其他嵌套对)。

成功!由罗的建议的启发,在最后,我使用这样的结构(不一定工作:。

$text = str_replace('([^>]|^)>([^>]|$)', '$1&gt;$2', $text); 
while ($len != strlen($text)){ 
    $len = strlen($text); 
    $text = preg_replace_callback('/>>([^>]+?)<</', "blockHashFunction", $text); 
} 

即我第一编码所有单>的,然后执行递归的preg_replace散列在这种情况下意味着,>>asdsad<<被替换为例如"\xFE:3:\xFE",在脚本的末尾,它被取消了哈希(好,更像是实际解码,我猜)到正确<blockquote>asdsad</blockquote>

+0

正则表达式的单个应用程序无法处理嵌套的项目。 – jswolf19 2011-03-28 10:54:58

正则表达式不适合这种类型的解析。实际上有一些RegEx引擎支持嵌套/平衡匹配,例如.NET Framework RegEx引擎(请参阅:http://blogs.msdn.com/b/bclteam/archive/2005/03/15/396452.aspx)。但是,我觉得这导致了非常复杂的模式。

如果您创建一个匹配开始或结束标签的正则表达式并手动创建所有匹配的树,那么您会更好。处理完整个字符串后,您可以放弃生成的集合中不需要的匹配。