我目前正在创建 bbcode 解析引擎,但遇到了我自己无法解决的情况。
问题是,我遇到了一个与此完全相同的问题: Windows 上的 Apache / PHP crash 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
(spacer) 之后的任何内容,直到它到达 tag closure ]
。
(?P<content>(?:[^[]|\[(?!/?(?P=tag)])|(?R))+?)
现在我在这里尝试匹配内容。这是棘手的部分。我正在寻找任何不是 [ 的字符,如果找到任何字符,则检查它是否不是我的结束标签或递归,并告诉正则表达式引擎这样做,直到...。
\[/(?P=tag)]
...找到结束标签。