PHP正则表达式不工作-在本地服务器上返回NULL,但在其他服务器上正常工作


PHP regex not working - returns NULL on local server, but works properly on other

我有以下正则表达式:

/'{'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示例,它仍然对我有效。所以你的其他代码肯定有问题;您可能希望启用完整的错误输出,以查看是否存在其他问题。