我对 PHP 和正则表达式一无所知,但我正在尝试为我的论坛修复一个损坏的插件。
我想替换以下内容:
<blockquote rel="blah">foo</blockquote>
与
<blockquote class="a"><div class="b">blah</div><div class="c"><p>foo</p></div></blockquote>
实际上,这部分很简单,我已经部分修复了插件来执行此操作。在调用 preg_replace_callback()
时使用以下正则表达式来进行替换:
/(<blockquote rel="([\d\w_ ]{3,30})">)(.*)(<\/blockquote>)/u
回调代码为:
return <<<BLOCKQUOTE
<blockquote class="a"><div class="b">{$Matches[2]}</div><div class="c"><p>{$Matches[3]}</p></div></blockquote>
BLOCKQUOTE;
这适用于我上面的示例(非嵌套 block 引用)。 但是,如果 block 引用是嵌套的,如下例所示:
<blockquote rel="blah">foo <blockquote rel="bloop">bar ...maybe another nest...</blockquote></blockquote>
这不起作用。所以我的问题是,如何使用正则表达式/PHP 组合替换所有嵌套 block 引用?我知道 PHP 中可以使用 (?R)
; 实现递归模式。以下正则表达式将从包含它们的字符串中提取所有嵌套的 block 引用:
/(<blockquote rel="([\d\w_ ]{3,30})">)(.*|(?R))(<\/blockquote>)/s
但从那时起,我不太确定在 preg_replace_callback()
回调中该怎么做,以将每个嵌套 block 引用替换为上述替换。
如有任何帮助,我们将不胜感激。
最佳答案
简单的答案是你不能使用正则表达式来做到这一点。任意深度的嵌套标签(或括号、方括号或任何内容)的语言不是常规,因此无法与常规表达式匹配。我建议您使用 DOM 解析器,或者 - 如果出于某种奇怪的原因绝对必要 - 编写您自己的解析方案。
复杂的答案是,您可能可以使用一些非常丑陋、hacky 的正则表达式和 PHP 代码来做到这一点,但老实说我不建议这样做。
另请参阅:The Chomsky hierarchy .
另请参阅:
关于php - 嵌套正则表达式...我一无所知!,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3951596/