【问题标题】:This simply regular expression is really slow, why?这个简单的正则表达式真的很慢,为什么?
【发布时间】:2017-08-25 12:05:05
【问题描述】:

我编写了这个非常简单的正则表达式,它检查整个字符串是否代表一个或多个十六进制数字(可选以“0x”开头,以逗号、减号或空格字符分隔):

/^((0x)?[0-9A-F]+[,\-\s]*)+$/i

对我来说,这个正则表达式非常简单,但是这个简单的测试完全使 Firefox 和 Edge 崩溃,Chrome 占用 100% CPU 使用大约 15 秒,然后返回预期结果“false”:

/^((0x)?[0-9A-F]+[,\-\s]*)+$/i.test("012345678901234567890123456789_0");

有人知道这里出了什么问题吗?

【问题讨论】:

标签: javascript regex performance hex


【解决方案1】:

当一个组包含两个子模式并且其中一个是可选的时,这是catastrophic backtracking(参见your regex demo)的常见情况。

您需要将模式重新组合为

/^(?:0x)?[0-9A-F]+(?:[,\s-]+(?:0x)?[0-9A-F]+)*$/i

现在,它将匹配:

  • ^ - 字符串开头
  • (?:0x)?[0-9A-F]+ - 十六进制数
  • (?:[,\s-]+(?:0x)?[0-9A-F]+)* - 零个或多个序列
    • [,\s-]+ - 1+ 个空格、,- 符号(如果必须匹配 1,则删除 +
    • (?:0x)?[0-9A-F]+ - 十六进制数
  • $ - 字符串结束。

请参阅regex demo

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-12
    • 1970-01-01
    • 2015-01-12
    • 1970-01-01
    • 2020-11-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多