嵌套的正则表达式......我很无能为力!

van*_*n00 2 php regex recursive-regex

当谈到PHP和正则表达式时我很无能,但我正在尝试为我的论坛修复一个破损的插件.

我想替换以下内容:

<blockquote rel="blah">foo</blockquote>
Run Code Online (Sandbox Code Playgroud)

<blockquote class="a"><div class="b">blah</div><div class="c"><p>foo</p></div></blockquote>
Run Code Online (Sandbox Code Playgroud)

实际上,这部分很简单,我已经部分修复了插件来执行此操作.正在使用以下正则表达式进行preg_replace_callback()替换:

/(<blockquote rel="([\d\w_ ]{3,30})">)(.*)(<\/blockquote>)/u
Run Code Online (Sandbox Code Playgroud)

回调代码是:

return <<<BLOCKQUOTE
<blockquote class="a"><div class="b">{$Matches[2]}</div><div class="c"><p>{$Matches[3]}</p></div></blockquote>
BLOCKQUOTE;
Run Code Online (Sandbox Code Playgroud)

这适用于我上面的例子(非嵌套的块引用).但是,如果块引用是嵌套的,例如在以下示例中:

<blockquote rel="blah">foo <blockquote rel="bloop">bar ...maybe another nest...</blockquote></blockquote>
Run Code Online (Sandbox Code Playgroud)

它不起作用.所以我的问题是,如何使用regex/PHP的组合替换所有嵌套的 blockquotes?我知道在PHP中可以使用递归模式(?R); 以下正则表达式将从包含它们的字符串中提取所有嵌套的blockquotes:

/(<blockquote rel="([\d\w_ ]{3,30})">)(.*|(?R))(<\/blockquote>)/s
Run Code Online (Sandbox Code Playgroud)

但是从那以后我不太确定在preg_replace_callback()回调中要做什么来用上面的替换来替换每个嵌套的blockquote.

任何帮助,将不胜感激.

eld*_*his 6

简单的答案是你不能用正则表达式做到这一点.任意深度的嵌套标签(或parens,或括号或任何东西)的语言不规则,因此无法与正则表达式匹配.我建议您使用DOM解析器,或者 - 如果出于某种奇怪的原因绝对必要 - 编写您自己的解析方案.

复杂的答案是你可能能够用一些非常丑陋,hacky的正则表达式和PHP代码来做到这一点,但我不建议它说实话.

另请参见:乔姆斯基层次结构.

另见: