JavaScript Regex Infinite Loop on Some Patterns

。_饼干妹妹 提交于 2021-02-16 20:18:15

问题


I am trying to use the exec method on the JavaScript Regex object and can get into an infinite loop where exec does not return a null depending on the expression.

Here is a test function I wrote to illustrate the problem. I ran it in Chrome 32. I am defining the Regex and match variables outside the loop. The max/Reached Max test is there to break out of the infinite loop.

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;
    }
  }
}

Here is a simple test that runs as expected.

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

Here is the regular expression I am trying to use. It extracts an optional variable name and a required XPath expression. This will go into an infinite loop that is only stopped by the test I added. It appears to get to the end of the input text and hang.

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

Here is the same test simplified. It still sends it into an infinite loop.

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

If the text includes a new-line, \n, it would hang at the character before it.

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

I would appreciate any help. Wes.


回答1:


The pattern .* matches the zero characters in the source string that come after the first match. It will keep on matching those zero characters forever. You could simplify a demonstration of that by matching against the empty string in the first place.

What you could do is quit when the match position stops changing.



来源:https://stackoverflow.com/questions/28838169/javascript-regex-infinite-loop-on-some-patterns

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!