php - 嵌套正则表达式...我一无所知!

标签 php regex recursive-regex

我对 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/

相关文章:

python - 在 Python 中使用正则表达式匹配嵌套结构

python - 正则表达式中的递归模式

PHP 未接收到 JavaScript 值

php - 用于用户代理的 Microsoft Edge 正则表达式

php - Python 或 PHP 中的感知哈希算法?

ruby - 为什么 String#split ("\n") 和 Array#join (' ' ) 比 String#gsub(/\n/, ' ' ) 更快?

python - 正则表达式 - 匹配未转义的字符

ruby-on-rails - 正则表达式匹配从字符串中获取正确数字的简单逻辑

php - ORDER BY Year DESC 不工作