PHP preg_replace崩溃了。仅适用于Regexp Masters

时间:2012-08-10 23:27:40

标签: php regex recursion preg-replace lookahead

你好吗?我会直言不讳。

我正在使用递归正则表达式,基本上删除单个或嵌套的< blockquote>代码。我只需要删除plain< blockquote> ...< / blockquote>文本,嵌套或不嵌套,并保留其他内容。

这个正则表达式完全按照我的要求完成工作(注意使用前瞻和递归)

$comment=preg_replace('#<blockquote>((?!(</?blockquote>)).|(?R))*</blockquote>#s',"",$comment);

但它有一个很大的问题:当$ comment很大(超过3500个字符长),apache崩溃(我假设分段错误)。

我需要一个问题的解决方案,但解决崩溃,使用更好的正则表达式自定义函数来执行工作也是如此。

如果您只是想了解如何删除嵌套的特定标签,我们非常欢迎您。

提前谢谢

1 个答案:

答案 0 :(得分:1)

男人,你的模式像疯子一样!甚至几百个字节的评论以崩溃结束。

使用preg_split()分割字符串会更简单,然后使用计数器来跟踪你的深度。当深度大于1时,你会丢弃文本。这是实施:

$tokens = preg_split('#(</?blockquote.*?>)#s', $comment, -1, PREG_SPLIT_DELIM_CAPTURE); 
$outsideTokens = array();
$depth = 0;
for($token = reset($tokens); $token !== false; $token = next($tokens)) { 
    if($depth == 0) {
        $outsideTokens[] = $token;
    }
    $delimiter = next($tokens);
    if($delimiter[1] == '/') {
        $depth--;
    } else {
        $depth++;
    }
}
$comment = implode($outsideTokens);

即使start标记包含属性,代码也应该有效。