views:

251

answers:

1

I wrote a Javascript RegExp test to detect date string format, I added an redundant "g" flag by mistake and found something interesting.

var s = "2009/03/10";
var regex=/^\d{4}[/]\d{2}[/]\d{2}$/g;
alert(regex.test(s));
alert(regex.test(s));
alert(regex.test(s));
alert(regex.test(s));

I got a 'true' followed by a 'false', then another 'true', then another 'false'.

If I use a loop to execute it, I found something more interesting, I got four "true" in IE and Safari, and true,false,true,false in FF, Chrome.

for (var i=0; i<4; i++)
{
  var s = "2009/03/10";
  var regex=/^\d{4}[/]\d{2}[/]\d{2}$/g;
  alert(regex.test(s));
}

Does anybody has idea to explain why the Javascript regex behaves like that and what cause browsers return different results? ( related to variable declaration and life scope? )

+5  A: 

When you use a global flag on a JS RegExp the "test" and "exec" methods each halt at the first match but keep a pointer to where they stopped searching in the string. That pointer can be inspected on the lastIndex property. When you call "test" or "exec" again it begins searching for a match starting at the lastIndex.

So, when you test a RegExp on a string that matches the entire string the lastIndex is set to the end of the string. The next time you test it starts at the end of the string, returns false, and sets lastIndex back to zero.

The MDC has a decent explanation of this behavior.

Prestaul
Thanks a lot, the MDC's explaination is very clear.
Darkthread
+1 thanks for the help, setting reg.lastIndex=0 before each test solved my problem.
bendewey