如何改进此正则表达式?它';s在非常短的文本上点击PHP的PREG_BACKTRACK_LIMIT_ERROR


How can this regex by improved? It's hitting the PREG_BACKTRACK_LIMIT_ERROR for PHP on very short text

以下正则表达式:

$common_tlds = 'us|me|com|net|org|ly|be|edu|gov|uk|ca|de|jp|fr|au|ru|ch|it|nl|se|no|es|mil|co';
$regex = '#(?:https?://)?([^.'s]+(?:[^'s.]|[^'s][^'s.])*'.(?:' . $common_tlds . ')[^.'s]*)#i';

此处使用:

preg_replace($regex,'<a href="http://$1" target="_blank">$1</a>', $text);

正在给我一个非常短的文本的PREG_BACKTRACK_LIMIT_ERROR。一个示例文本是:

Life cant always give you the best shoes,handbags,clothes but it can give you the best creations.

我知道,有更好的链接在线查找正则表达式,但我很好奇我的正则表达式中是什么导致了大规模回溯,以及我如何改进它。谢谢!

试试这样的东西:

$regex = '#(?:https?://)?([^.'s]+(?:'.[^.'s]+)*'.(?:' . $common_tlds . '))#i';

评论:

  • 你看到了灾难性的回溯——你的模式有太多的方法无法匹配字符串
  • [^.'s]+(?:'.[^.'s]+)*只允许一种匹配域的方式,即在点处锚定
  • [^.'s]*-从末尾删除,不确定它在tld之后应该做什么。如果你想匹配像.co.il这样的域,你可能需要另一个点:(?:'.[^.'s]+)?
  • 您可能希望在开始时使用'b,以避免与(google.com匹配