RegExp.exec () returns NULL sporadically

I'm seriously going crazy about this, and I have already spent a disproportionate amount of time trying to figure out what is going on here. So please give me a hand =)

I need to do some RegExp string matching in JavaScript. Unfortunately, this behaves very strangely. This code:

var rx = /(cat|dog)/gi; var w = new Array("I have a cat and a dog too.", "There once was a dog and a cat.", "I have a cat and a dog too.", "There once was a dog and a cat.","I have a cat and a dog too.", "There once was a dog and a cat.","I have a cat and a dog too.", "There once was a dog and a cat.","I have a cat and a dog too.", "There once was a dog and a cat.","I have a cat and a dog too.", "There once was a dog and a cat.","I have a cat and a dog too.", "There once was a dog and a cat."); for (var i in w) { var m = null; m = rx.exec(w[i]); if(m){ document.writeln("<pre>" + i + "\nINPUT: " + w[i] + "\nMATCHES: " + m.slice(1) + "</pre>"); }else{ document.writeln("<pre>" + i + "\n'" + w[i] + "' FAILED.</pre>"); } } 

It returns "cat" and "dog" for the first two elements, as it should be, but then some exec() -calls start returning null . I do not understand why.

I posted a fiddle here where you can run and edit code.

And while I tried it in Chrome and Firefox.

Hurrah!

/ Christofer

+47
javascript regex
Jan 18 2018-11-18T00:
source share
4 answers

Oh, there it is. Since you are defining a global regex expression, it matches the first cat and second pass of the dog loop. So basically you just need to reset your regular expression (its internal pointer). Wed this:

 var w = new Array("I have a cat and a dog too.", "I have a cat and a dog too.", "I have a cat and a dog too.", "I have a cat and a dog too."); for (var i in w) { var rx = /(cat|dog)/gi; var m = null; m = rx.exec(w[i]); if(m){ document.writeln("<p>" + i + "<br/>INPUT: " + w[i] + "<br/>MATCHES: " + w[i].length + "</p>"); }else{ document.writeln("<p><b>" + i + "<br/>'" + w[i] + "' FAILED.</b><br/>" + w[i].length + "</p>"); } document.writeln(m); } 
+44
Jan 18 2018-11-18T00:
source share

The regex object has a lastIndex , which is updated when exec run. Therefore, when you perform a regular expression, for example, "I have a cat and a dog too." lastIndex set to 12. The next time you run exec in the same regular expression object, it starts looking for index 12. Thus, you must reset lastIndex between each run.

+45
Jan 18 '11 at 1:59 p.m.
source share

Two things:

  • The indicated need to reset when using the g (global) flag. To solve this problem, I recommended simply assigning 0 to the lastIndex member of the RegExp object. This improves performance than destroys and restores.
  • Be careful when using the in keyword to traverse an Array object , because this can lead to unexpected results with some libs. Sometimes you need to check with something like isNaN(i) , or if you know that it has no holes, use the classic one for the loop.

The code may be:

 var rx = /(cat|dog)/gi; w = ["I have a cat and a dog too.", "There once was a dog and a cat.", "I have a cat and a dog too.", "There once was a dog and a cat.","I have a cat and a dog too.", "There once was a dog and a cat.","I have a cat and a dog too.", "There once was a dog and a cat.","I have a cat and a dog too.", "There once was a dog and a cat.","I have a cat and a dog too.", "There once was a dog and a cat.","I have a cat and a dog too.", "There once was a dog and a cat."]; for (var i in w) if(!isNaN(i)) // Optional, check it is an element if Array could have some odd members. { var m = null; m = rx.exec(w[i]); // Run rx.lastIndex = 0; // Reset if(m) { document.writeln("<pre>" + i + "\nINPUT: " + w[i] + "\nMATCHES: " + m.slice(1) + "</pre>"); } else { document.writeln("<pre>" + i + "\n'" + w[i] + "' FAILED.</pre>"); } } 
+14
Jan 14 '14 at 20:26
source share

I had a similar problem using only / g, and the proposed solution here did not work for me in FireFox 3.6.8. I got a script with

 var myRegex = new RegExp("my string", "g"); 

I add this if someone else has a problem that I encountered with the above solution.

+4
Jul 11 2018-11-11T00:
source share



All Articles