【问题标题】:Why is this regular expression so slow?为什么这个正则表达式这么慢?
【发布时间】:2013-07-31 19:05:11
【问题描述】:

我正在尝试从字符串中修剪前导和尾随空格和换行符。换行符写成\n(两个单独的字符,斜线和n)。换句话说,它是一个字符串文字,而不是一个 CR LF 特殊字符。

例如,这个:

\n \nRight after this is a perfectly valid newline:\nAnd here is the second line. \n

应该变成这样:

Right after this is a perfectly valid newline:\nAnd here is the second line.

我想出了这个解决方案:

text = text
        .replace(/^(\s*(\\n)*)*/, '') // Beginning
        .replace(/(\s*(\\n)*)*$/, '') // End

根据RegexPal,这些模式匹配得很好。

但是,第二个模式(匹配字符串的结尾)需要很长时间——在 Chrome 中,只有几个段落和几个尾随空格的字符串大约需要 32 秒。第一个模式在同一个字符串上非常快(毫秒)。

Here is a CodePen to demonstrate it.

为什么这么慢?有没有更好的方法来解决这个问题?

【问题讨论】:

  • @Romoku 我同意另一个问题是关于同一主题的,但我没有看到任何关于正则表达式性能的信息。
  • 你有大量的可选性,甚至是嵌套的可选性。那很慢。做.replace(/^\s+/).replace(/\s+$/)
  • 查找catastrophic backtracking。这几乎肯定是问题所在。
  • 他想将 \n 匹配为字符串文字,而不是 CR LF。这就是他用前三个段落解释的内容。这不是灾难性的回溯。

标签: javascript regex performance


【解决方案1】:

之所以需要这么长时间是因为你有一个* 量化了另外两个*

可以在PHP manual 中找到一个很好的解释,但我认为 JavaScript 不支持一次性子模式。

我建议改用这个正则表达式:

text = text.replace(/^(?:\s|\\n)+|(?:\s|\\n)+$/g,"");

【讨论】:

【解决方案2】:

不是一个好的答案,但一种解决方法是反转字符串,并将正则表达式中的 \n 反转为 n\(作为开始),应用它,然后将字符串反转回来。

【讨论】:

  • 任务过于复杂了……真的
猜你喜欢
  • 2019-03-12
  • 1970-01-01
  • 2020-11-27
  • 2012-10-08
  • 2014-01-23
  • 1970-01-01
  • 2018-08-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多