【发布时间】:2011-04-06 12:02:05
【问题描述】:
我目前正在创建 bbcode 解析引擎,但遇到了我自己无法解决的情况。
问题是,我遇到了一个和这个完全一样的问题: Apache / PHP on Windows crashes with regular expression
这意味着如果我做出类似下面示例的操作,Apache 会因为递归计数达到 690(PCRE 的内存限制为 1MB)而崩溃:
$txt = '[b]'.str_repeat('a', 338).'[/b]'; // if I change repeat count to lower value it's ok
$regex = '#\[(?P<attributes>(?P<tag>[a-z0-9_]*?)(?:=.*?|\s.*?|))](?P<content>(?:[^[]|\[(?!/?(?P=tag)])|(?R))+?)\[/(?P=tag)]#mi';
echo preg_replace_callback($regex, function($matches) { return $matches['content']; }, $txt);
所以我需要以某种方式在我的正则表达式中尽量减少 * 和 + 的需求,但这就是我没有想法的地方,所以我想也许你可以提出一些建议。
欢迎使用其他解析 bbcode(可以处理嵌套标签)的方法。 但是我不想使用已经构建的类或其他东西。我喜欢自己做事!
我还研究了 PECL 和 Pear HTML_BBCodeParser。但我不希望我的应用程序依赖于扩展。更有可能我会做一些脚本来检查那个扩展,如果它不存在,请使用我在这里尝试做的 BBCode 解析器。
对不起,如果我的描述令人沮丧,我不擅长英语^^
编辑。所以正则表达式解释:
\[(?P<attributes>(?P<tag>[a-z0-9_]*?)(?:=.*?|\s.*?|))]
这是我的开始标签。我使用了命名组。使用“标签”标识标签,使用“属性”标识标签属性。也可以将标签视为一个属性。那么这里发生了什么?我尝试匹配一个标签,当一个标签匹配时,我尝试匹配= 符号之后的任何内容或\s(空格)之后的任何内容,直到它到达标签关闭]。
(?P<content>(?:[^[]|\[(?!/?(?P=tag)])|(?R))+?)
现在我在这里尝试匹配内容。这是棘手的部分。我正在寻找任何不是 [ 的字符,如果找到任何字符,则检查它是否不是我的结束标记或递归,并告诉正则表达式引擎这样做,直到....
\[/(?P=tag)]
...找到结束标记。
【问题讨论】:
-
“我也研究了 PECL 和 Pear HTML_BBCodeParser。但我不希望我的应用程序依赖于扩展”——我认为这个选项比重新发明轮子更可取。
-
I like to do things on my own!- 为什么?您是否也编写自己的正则表达式引擎?还是你自己的 php 解释器/运行时? -
顺便说一句:您可能希望将正则表达式代码分散到多行并用 cmets 解释这些部分。我猜这可以提高你获得帮助的机会。
-
感谢您的提示,VolkerK。我说的“我喜欢自己做事!”并不是这个意思。哦,好吧..让我们忘记它。我已经解释了代码,希望现在可以了。
-
你能举一个你遇到限制的字符串的例子吗?
标签: php regex bbcode recursive-regex