3

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.

3
  • Note that you're logging "Reached Max" when in fact it's reached the end of the matches, not necessarily after it's done the max (10 matches by default) - ie are you sure it's actually stuck in a loop? Commented Mar 3, 2015 at 17:34
  • The end of matches is when match is null which I may never reach. I've had to kill the page before the adding the test. I added the index == lastIndex when I discovered the pattern that they were both the same while in the infinite loop. Before that I only had max to break me out of the infinite loop. Commented Mar 3, 2015 at 18:13
  • Ah yes, I see how that's covered in your question too, now Commented Mar 3, 2015 at 18:48

1 Answer 1

4

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Good catch but I would think that exec would return null when it is at the end of the input.
@Wes it won't return null because the pattern does really match.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.