我有以下正则表达式:
/'{'s?joomla-tag's+(.*<+.+>+.*)'s?'}/is
和以下代码:
$regex = "/'{'s?joomla-tag's+(.*<+.+>+.*)'s?'}/is";
$replace = '<div class="someclass">$1</div>';
$text = preg_replace( $regex, $replace, $text );
但是,不幸的是,它无法匹配以下代码(尽管如此,它应该匹配):
.... many html lines .......
<p>123{joomla-tag Lore<strong>m</strong> ip</p>
<p>sum dolor sit amet}</p>
.... many html lines .......
查看真实示例:http://pastebin.com/WSQyrmxd
出了什么问题:正则表达式还是其他什么?你能告诉我正确的变体吗?在RegExr中,一切都很顺利,但在PHP中则不然。
在本地服务器上,我只是在preg_replace之后得到NULL
编辑:最后,我找到了一个解决方案:(感谢sg3s提出的想法)http://www.pelagodesign.com/blog/2008/01/25/wtf-preg_replace-returns-null/
你说你解决了这个问题,但如果你的解决方案是增加backtrack_limit
设置,那就不是解决方案。事实上,你以后可能会遇到更大的问题。你需要找出为什么它会做这么多回溯。
在'{'s?joomla-tag's+
定位标签的开头之后,第一个.*
最初吞噬文档的剩余部分。然后它开始后退,试图让正则表达式的其余部分匹配。当它达到<+
可以匹配的点时,.+
再次消耗文档的其余部分,另一波回溯开始了。在那之后还有一个.*
,你让它做了大量荒谬的不必要的工作。
这就是经验法则的原因
如果可以使用更具体的字符,请不要使用点元字符(尤其是
.*
或.+
)。如果确实使用了点,请不要在单行或DOTALL模式下使用它(即/s
修饰符或其内联(?s)
形式)。
在这种情况下,您知道匹配应该在下一个大括号(}
)处结束,所以在此之前不要让它匹配任何大括号:
'{'s?joomla-tag's+([^}]*)'}
听起来这可能是由于PCRE正则表达式引擎耗尽堆栈而导致的:pcre.recursion_limit
错误。我以前见过这种情况(但通常症状更严重,即完全崩溃Web服务器!)请注意,这类问题通常会在本地服务器而不是远程服务器上表现出症状,尤其是当本地系统在Windows下运行Apache时(httpd.exe
的Win32版本只有256KB的堆栈空间)。
CCD_ 14在PCRE库中遇到错误时返回CCD_。您可以使用preg_last_error()
函数来获取最后一个错误,并打印出这样的消息:
$pcre_err = preg_last_error(); // PHP 5.2 and above.
if ($pcre_err === PREG_NO_ERROR) {
$msg = 'Successful non-match.';
} else {
// preg_match error!
switch ($pcre_err) {
case PREG_INTERNAL_ERROR:
$msg = 'PREG_INTERNAL_ERROR';
break;
case PREG_BACKTRACK_LIMIT_ERROR:
$msg = 'PREG_BACKTRACK_LIMIT_ERROR';
break;
case PREG_RECURSION_LIMIT_ERROR:
$msg = 'PREG_RECURSION_LIMIT_ERROR';
break;
case PREG_BAD_UTF8_ERROR:
$msg = 'PREG_BAD_UTF8_ERROR';
break;
case PREG_BAD_UTF8_OFFSET_ERROR:
$msg = 'PREG_BAD_UTF8_OFFSET_ERROR';
break;
default:
$msg = 'Unrecognized PREG error';
break;
}
}
echo($msg);
我已经用相关问题的答案详细解释了这个错误。参见:
preg_match函数中的RegExp返回浏览器错误
PHP正则表达式:这段代码有什么问题吗?
使用CodeIgniter 使用正则表达式最小化最终HTML输出
祝你好运!
它对我有效。
请注意,从HTML的角度来看,您的替换不会创建有效的结构。
使用全文
即使提供了完整的HTML示例,它仍然对我有效。所以你的其他代码肯定有问题;您可能希望启用完整的错误输出,以查看是否存在其他问题。