javascript - 为什么这个 JavaScript 正则表达式很慢?

标签 javascript regex

<分区>

var email = '[John Smith] <johnsmith@gmail.com>';

var re1 = /.*<+(.*)+>.*/;
var re2 = /.*\[+(.*)+\].*/;

var address = email.replace(re1, "$1");
var name = email.replace(re2, "$1");

我发现第二个正则表达式(获取名称)运行速度非常慢。但第一个很好。为什么会这样,是否有更好的方法来获取我需要的字符串?

最佳答案

你的正则表达式之所以慢是因为它们写得很糟糕

现在,让我们继续说说它们为什么不好。

您的第一个表达式有一堆 不必要的标记。如前导和尾随.* - 他们没有区别。其次,你已经量化了< 0 到 inf 次。为什么?你想匹配<<<<<<<<email>吗?或 email> ?最后,您量化了一个重复组。这太可怕了,因为

  1. 量化的捕获组会覆盖自己
  2. 由于上面的陈述,使用捕获组是没有意义的,因此它使用了不必要的资源。

好的,这是第一个表达式。第二个更糟糕,即使你刚刚切换了<>对于 [] .为什么你会问?我会告诉你为什么。 因为它不匹配。您可能会问,为什么这会如此糟糕?因为它会产生我们所说的灾难性回溯。您可能想知道为什么这样做?我会告诉你原因:

.*会尽量匹配。事实上,一开始,它会消耗整个字符串。显然失败了,所以它回溯了很多次,直到它可以匹配第一个 [。 .太棒了,现在引擎已经在字符串的第一个位置找到了文字 [ 的匹配项(因此使 .* 不匹配)。现在是下一个标记,.*由于其贪婪的性质,将再次匹配所有内容。这不起作用,因此引擎回溯。它会一直尝试这样做,直到它匹配字符串。问题是,它永远不会。因为您的贪婪量词被需要 1 个或多个匹配项的量化组包围。

现在,你如何解决这个问题?好吧,你可以简单地删除 +从小组后面。那会解决它。您的正则表达式仍然很糟糕,但它们不会导致引擎回溯一百万次。我们怎样才能进一步改进它?通过使用否定字符类。

/\[([^]]+)\] <([^>]+)>/

在此处查看正则表达式的演示:http://regex101.com/r/wS2jN0

如果您一开始使用 regex101.com,您会立即注意到回溯问题:http://regex101.com/r/vB8xB0

关于javascript - 为什么这个 JavaScript 正则表达式很慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14188107/

相关文章:

javascript - JSON.stringify(objExtraParam) 给出错误的日期

javascript - 隐藏以前的 HTML 桌面通知

javascript - 为什么这个正则表达式的第二部分不匹配?

javascript - 将字符串切割成 'variable' 长 block

Javascript正则表达式匹配部分字符串而不是整个字符串

javascript - Angularjs,首先总是选择框创建空白选项

javascript - replaceWith 后的 Dom 就绪事件

javascript - AngularJS:点击时的 CSS 动画 (ngClick)

Java 正则表达式 : How to search a text or a phrase in a large text

regex - 使用匹配约束进行验证验证-正则表达式