【问题标题】:JavaScript regex freezing browserJavaScript 正则表达式冻结浏览器
【发布时间】:2021-12-02 08:41:03
【问题描述】:

我在 JavaScript 中使用以下正则表达式来验证输入字段:

    <textarea
           id="kpf-message-textarea"
           class="message-area"
           name="message"
           maxlength="1000"
           aria-describedby="kpf-message-extra-text"
           aria-invalid="true"
           tabindex={this.kpfTabindex}
           value={this.message}
            onInput={(event) => this._handleChange(event)}>
           </textarea>


this.message.match(/^([A-Za-z]|[0-9]| 
[ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ]|[ \\.^°!"²§³$%&\/\\{\\}\\ 
(\\)=?´`@€+-\\*~'#<>|µ,;:_<CR><LF>]|[\n])+$/)

对于以下 30 个大写字母和一个无效字符的模式,它会导致浏览器挂起,只有再次关闭和打开浏览器才有帮助:

      ABCDEFGHIJKLMNOPAAAAAAAAAAAAAA¼

这里有什么问题?

【问题讨论】:

  • 这是由于灾难性的回溯。如果模式无法匹配,它将回溯并尝试所有选项。为什么不能没有所有单独的字符类? ^[A-Za-z0-9ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ \\.^°!"²§³$%&amp;\/{} ()=?´`@€+*~'#&lt;&gt;|µ,;:_&lt;CR&gt;&lt;LF&gt;\n-]+$regex101.com/r/S7ZWvH/1
  • 你也可以在你尝试这个的地方发布实际的 JavaScript,这样我们可以为你提供最好的帮助(什么是“消息”?,我们可以假设那个字符串示例吗?
  • 我添加了更多信息
  • @Thefourthbird 我不明白你的意思吗?如何改进/纠正此正则表达式以使其正常工作?
  • @Thefourthbird 我已经尝试过你的建议和它的工作,谢谢:) 现在,如果你能简单地解释一下为什么它不能与字符组一起工作,或者给我一个相关的来源?我找到了一些与灾难性回溯相关的答案,但不明白这个问题。

标签: javascript regex typescript


【解决方案1】:

由于catastrophic backtracking,模式超时。

它不能匹配最后的字符¼,它仍然会尝试探索(回溯)所有路径。对于外部重复组,以及该组内的交替,有很多选择。

在字符类中使用[&lt;CR&gt;&lt;LF&gt;][&gt;&lt;CFLR]是一样的,如果要匹配回车或换行可以使用\r\n

当您对所有单个字符匹配(没有量词的字符类)使用替换 | 时,您可以将所有字符类合并为一个字符类并重复该字符类 1 次或多次。

^[A-Za-z0-9ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ \\.^°!"²§³$%&/{} ()=?´`@€+*~'#<>|µ,;:_\r\n-]+$

Regex demo

一个简化的例子:

function handleChange() {
  let elm = document.getElementById("kpf-message-textarea");
  if (/^[A-Za-z0-9ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ \\.^°!"²§³$%&/{} ()=?´`@€+*~'#<>|µ,;:_\r\n-]+$/.test(elm.value)) {
    console.log("Match: " + elm.value);
  } else {
    console.log("No match: " + elm.value);
  }
}
<textarea id="kpf-message-textarea" class="message-area" name="message" maxlength="1000" aria-invalid="true" onInput=handleChange()>
</textarea>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-10
    • 2016-12-10
    • 2010-09-21
    相关资源
    最近更新 更多