【问题标题】:JavaScript Regex Infinite Loop on Some Patterns某些模式上的 JavaScript 正则表达式无限循环
【发布时间】:2015-03-03 17:31:03
【问题描述】:

我正在尝试在 JavaScript Regex 对象上使用 exec 方法,并且可能会进入无限循环,其中 exec 不会根据表达式返回 null。

这是我为说明问题而编写的一个测试函数。我在 Chrome 32 中运行它。我在循环外定义了 Regexmatch 变量。 max/Reached Max 测试可以打破无限循环。

function textExec(reg, text, max) {
  max = max || 10
  var match = null;
  while (match = reg.exec(text)) {
    console.log(match);
    console.log(match.length + " " + match.index + "," + reg.lastIndex);
    if (--max < 0 || match.index == reg.lastIndex) {
      console.log('Reached Max');
      break;
    }
  }
}

这是一个按预期运行的简单测试。

textExec(/(o[a-z])/g, "body=//soap:Body");
["od", "od", index: 1, input: "body=//soap:Body"]
2 1,3
["oa", "oa", index: 8, input: "body=//soap:Body"]
2 8,10
["od", "od", index: 13, input: "body=//soap:Body"]
2 13,15

这是我尝试使用的正则表达式。它提取一个可选的变量名和一个必需的 XPath 表达式。这将进入一个无限循环,仅由我添加的测试停止。它似乎到达输入文本的末尾并挂起。

textExec(/(([a-zA-Z0-9_-]*)=)?(.*)/g, "body=//soap:Body");
["body=//soap:Body", "body=", "body", "//soap:Body", index: 0, input: "body=//soap:Body"]
4 0,16
["", undefined, undefined, "", index: 16, input: "body=//soap:Body"]
4 16,16
Reached Max

这是相同的简化测试。它仍然将其发送到无限循环中。

textExec(/.*/g, "body=//soap:Body");
["body=//soap:Body", index: 0, input: "body=//soap:Body"]
1 0,16
["", index: 16, input: "body=//soap:Body"]
1 16,16
Reached Max

如果文本包含换行符\n,它将挂在它前面的字符处。

textExec(/.*/g, "//soap:Envelope\n//soap:Body");
["//soap:Envelope", index: 0, input: "//soap:Envelope?//soap:Body"]
1 0,15
["", index: 15, input: "//soap:Envelope\n//soap:Body"]
1 15,15
Reached Max

如果有任何帮助,我将不胜感激。 韦斯。

【问题讨论】:

  • 请注意,您正在记录“达到最大值”,而实际上它已经达到了比赛的结尾,不一定是在完成最大值之后(默认情况下为 10 场比赛) - 即您确定它实际上卡住了在循环中?
  • 匹配结束是match 为空,我可能永远也达不到。在添加测试之前,我不得不杀死该页面。当我发现它们在无限循环中相同的模式时,我添加了 index == lastIndex。在此之前,我只有 max 才能让我摆脱无限循环。
  • 啊,是的,我知道你的问题也涵盖了这一点,现在

标签: javascript regex


【解决方案1】:

模式.* 匹配源字符串中第一个匹配之后出现的零个字符。它将永远匹配那些零字符。您可以通过首先匹配空字符串来简化演示。

你可以做的是在匹配位置停止变化时退出。

【讨论】:

  • 很好,但我认为exec 在输入结束时会返回 null。
  • @Wes 它不会返回 null,因为该模式确实匹配。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多