PHP preg_替换崩溃。仅适用于Regexp Masters

PHP preg_替换崩溃。仅适用于Regexp Masters,php,regex,recursion,preg-replace,lookahead,Php,Regex,Recursion,Preg Replace,Lookahead,你好吗?我会直截了当地说 我使用的是一个递归正则表达式,它基本上删除了单个或嵌套的标记。我只需要删除平原。。。文本,嵌套与否,并保留这些文本之外的内容 这个正则表达式完全按照我所希望的方式完成工作(注意前瞻和递归的使用) $comment=preg#u replace('#((?!()).|(?R))*#s',“”,$comment); 但是它有一个大问题:当$comment很大(超过3500个字符长)时,apache崩溃(我假设是分段错误) 我需要一个问题的解决方案,但是解决崩溃,使用一个更

你好吗?我会直截了当地说

我使用的是一个递归正则表达式,它基本上删除了单个或嵌套的标记。我只需要删除平原。。。文本,嵌套与否,并保留这些文本之外的内容

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

$comment=preg#u replace('#((?!()).|(?R))*#s',“”,$comment);
但是它有一个大问题:当$comment很大(超过3500个字符长)时,apache崩溃(我假设是分段错误)

我需要一个问题的解决方案,但是解决崩溃,使用一个更好的regexp或一个自定义函数也可以解决问题

如果您只是对如何删除嵌套的特定标记有一些想法,欢迎使用


提前谢谢你

老兄,你的模式真是太疯狂了!即使是几百字节的注释也会以崩溃告终

使用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);
$tokens=preg#u split(“#()#s”,$comment,-1,preg#u split#u DELIM#u CAPTURE);
$outsideTokens=array();
$depth=0;
对于($token=reset($tokens);$token!==false;$token=next($tokens)){
如果($depth==0){
$outsideTokens[]=$token;
}
$delimiter=next($tokens);
if($delimiter[1]=='/')){
$depth--;
}否则{
$depth++;
}
}
$comment=内爆($outsideTokens);

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

请避免使用正则表达式解析HTML。改用.Segfault==可能是无限递归。您确定这仅仅是字符串的大小,还是它的内容导致了问题?尽管@Truth说的是真话(ha!),但HTML解析器对于这项工作来说是一个更好的工具。如果您必须坚持使用正则表达式,并且您确信该表达式符合您的需要,请尝试在其上添加一个
S
(研究)标志,我已经看到它修复了许多错误。@事实祝贺您,您似乎找到了一种方法,可以用该注释打破CSS。Skillz…@Dandy是一个使用HTML解析器从字符串中删除块引号的示例。谢谢大家。你们都很有帮助,我选择了@cleong解决方案。我真的很感激。哇!你刚刚做到了。我想不出来,你就这么做了!祝贺你,非常感谢!
$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);