为什么preg_match_all会在这么多字符之后输出?

时间:2010-07-16 02:03:15

标签: php limit preg-match-all

我的preg_match_all语句出了问题。它一直在完美地工作,因为我一直打字一篇文章,但是在它通过一定长度之后突然停止了所有的工作。这是一个已知的问题,在这么多字符之后它只是没有任何吗?

$number = preg_match_all("/(<!-- ([\w]+):start -->)\n?(.*?)\n?(<!-- \\2:stop -->)/s", $data, $matches, PREG_SET_ORDER);

它一直工作得很好并且适用于其他页面,但是一旦那篇文章超过了一定长度,它就停止了那篇文章的工作。我可以使用另一种解决方案使其适用于更长的文本块吗?正在处理的文章长度约为33,000个字符(包括空格)。

之前我问过这样的问题,但只得到了一个我从未真正测试过的答案。上一次我刚刚找到另一种方法来解决这个特定情况,但这次没有办法绕过它,因为它只是一篇文章。我尝试将pcre.backtrack_limitpcre.recursion_limit更改为甚至500,000,完全没有效果。关于为什么会发生这种情况还有什么其他的想法,以及我可以做些什么来让它继续工作,甚至对于这些大量的文本块?一个30,000个字符的限制似乎有点低,只有5,000-6,000个字(这个约为5,700个)。分开它并不是一个真正的选择,因为它不会找到开始和停止,如果它们在两个单独的文本块中。

2 个答案:

答案 0 :(得分:1)

我碰到过这一次,然后我能解决它的唯一方法是拆分字符串。您可以explode()preg_split()

从我的源代码中引用字面:

    // regexps have failed miserably on very large tables...
    $parts = explode("<table",$html);

但这是两年前的事。

答案 1 :(得分:0)

看起来你正在使用HTML。您可能需要考虑使用各种解析器之一。例如,DOM有a specific class for comments,因此我们知道它可以与它们一起使用。不幸的是DOM使用起来有点尴尬。

另一种选择可能是使用XMLReader,它将XML作为流读取并在整个过程中将其作为令牌处理。它似乎明白了什么是评论。我自己从来没有用过它,所以我不能告诉你它有多好用。 (您可以使用DOM的loadHTMLsaveXML方法将HTML转换为XML,假设它不是太糟糕的形式。)

最后,您可以考虑为自定义注释编写tokenizer或parser。它应该不会太难,并且可能比你学习我已经指出的任何XML解决方案更快地进行攻击。