【问题标题】:Why does this regex take so long to execute?为什么这个正则表达式需要这么长时间才能执行?
【发布时间】:2016-04-24 08:28:53
【问题描述】:

我创建了 regex,它应该在相邻的 <span> 标记内移动文本。

const fix = (string) => string.replace(/([\S]+)*<span([^<]+)*>(.*?)<\/span>([\S]+)*/g, "<span$2>$1$3$4</span>")

fix('<p>Given <span class="label">Butter</span>&#39;s game, the tree counts as more than one input.</p>')
// Results in:
'<p>Given <span class="label">Butter&#39;s</span> game, the tree counts as more than one input.</p>'

但是,如果我将一个字符串传递给它,其中没有文本触及 &lt;span&gt; 标记,则需要几秒钟才能运行。

我正在 ChromeElectron 上对此进行测试。

【问题讨论】:

  • 用正则表达式解析 HTML?嗯。
  • 如果您只关心span,请使用:- &lt;span([^&lt;]+)&gt;(.*?)&lt;\/span&gt;..regex101.com/r/fL9rG0/1
  • 我还看到 ([^&lt;]+)* 一个额外的 * 我认为不需要
  • 还有一件事:- 如果&lt;/span&gt; 不存在,您的正则表达式将出现灾难性的回溯
  • 不要这样做是最好的答案。使用任何methods for parsing HTML in JavaScript

标签: javascript regex performance


【解决方案1】:

([\S]+)*([^&lt;]+)* 是在没有&lt;/span&gt; 时导致catastrophic backtracking 的罪魁祸首。您需要将您的正则表达式修改为

([\S]*)<span([^<]*)>(.*?)<\/span>([\S]*)

它会工作,但它仍然不是efficient

为什么要为\S 使用字符类?以上简化为

(\S*)<span([^<]*)>(.*?)<\/span>(\S*)

如果您只关心span 的内容,请改用它

<span([^<]*)>(.*?)<\/span>

检查here

注意:最后不要用正则表达式解析 HTML,如果有工具可以更容易地做到这一点

【讨论】:

  • 知道如何解决吗?
  • @demux 我正在写它
  • 重点是将接触span的文本移动到span,所以不,我不仅关心内容
  • @demux 然后你可以使用第二个捕获组
  • @demux 你想将&lt;p&gt;Given&amp;#39;s 移动到span 标签内吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-22
  • 2012-04-29
  • 1970-01-01
  • 1970-01-01
  • 2014-08-13
相关资源
最近更新 更多