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? )
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
lastIndexproperty. When you call ‘test’ or ‘exec’ again it begins searching for a match starting at thelastIndex.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 setslastIndexback to zero.The MDC has a decent explanation of this behavior.