Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Interesting test of Javascript RegExp [duplicate]

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? )

like image 982
Darkthread Avatar asked Mar 03 '09 02:03

Darkthread


1 Answers

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.

like image 130
Prestaul Avatar answered Sep 23 '22 05:09

Prestaul