我有以下正则表达式:
/\{\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/
答案 0 :(得分:5)
你说你解决了这个问题,但如果你的解决方案是增加backtrack_limit
设置,那不是解决方案。事实上,你可能会在以后为更大的问题做好准备。你需要找出为什么它正在进行如此多的回溯。
\{\s?joomla-tag\s+
找到代码的开头后,第一个.*
最初会吞噬文档的其余部分。然后它开始后退,试图让正则表达式的其余部分匹配。当它到达<+
可以匹配的点时,.+
会再次消耗文档的其余部分,并开始另一波回溯。在此之后又有了.*
,你正在做一些荒谬的不必要的工作。
这是经验法则的原因,
如果您可以使用更具体的内容,请勿使用点元字符(尤其是
.*
或.+
)。如果您使用点,请不要在单行或DOTALL模式下使用它(即/s
修饰符或其内联,(?s)
形式。
在这种情况下,您知道匹配应该在下一个右大括号(}
)结束,所以在此之前不要让它匹配任何大括号:
\{\s?joomla-tag\s+([^}]*)\}
答案 1 :(得分:4)
由于PCRE正则表达式引擎耗尽堆栈,这听起来可能是:pcre.recursion_limit
错误。我以前见过这个(但通常症状更严重 - 即完全崩溃网络服务器!)请注意,这类问题经常会在本地服务器而不是远程服务器上出现症状,特别是在本地系统运行Apache时在Windows下(httpd.exe
的Win32版本只有256KB的堆栈空间)。
preg_replace()
在PCRE库中遇到错误时返回NULL
。您可以使用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);
我已经通过对相关问题的回答详细解释了这个错误。参见:
RegExp in preg_match function returning browser error
PHP regex: is there anything wrong with this code?
Minifying final HTML output using regular expressions with CodeIgniter
祝你好运!答案 2 :(得分:2)
请注意,从HTML的角度来看,您的替代品不会创建有效的结构。
即使使用提供的完整HTML示例,它仍然是works for me。所以你的其他代码必须有一些错误;您可能希望启用完整错误输出以查看是否存在其他问题。