如何改进这个正则表达式以避免PREG_BACKTRACK_LIMIT_ERROR?

时间:2015-01-23 13:21:46

标签: php regex

我有以下正则表达式。

(From:.*)<(.+) (.+)@first abc.com>

我正在使用以下代码来解析电子邮件地址

$mimeFile = preg_replace_callback( "/(From:.*)<(.+) (.+)@first abc.com>/", 
function($matches) { 
    return $matches[1].'<'.strtolower($matches[2]).'.'.strtolower($matches[3]).'@xyz.com>'; 
}, $content );

适用于小内容,但当内容很大时,它会提供PREG_BACKTRACK_LIMIT_ERROR。

如何改善我的正则表达式?

提前致谢。

1 个答案:

答案 0 :(得分:0)

您可以使用:

$mimeFile = preg_replace_callback('~From:[^<\n]*<\K([^>@ ]+) ([^>@]+)@first abc\.com>~', function($m) { 
    return strtolower($m[1] . '.' . $m[2]) . '@xyz.com>'; 
}, $content );

您的模式问题来自于使用连续.*.+过于宽松,并且当空格或子串@first abc.com>.+时会导致catastrophic backtracking不存在。

在这两个示例中,我使用了排除我需要停止的字符的字符类,而不是使用[^@>]+。 <{1}}只要遇到@>就会停止。

注意:当您编写类似[^a]+a的内容时,pcre正则表达式引擎会自动将其优化为[^a]++a(它使量词possessive