Reputation: 18557
I've been debugging this one application for a while and it led me to this test case. When I run it in firefox 3.6.x it only works 50% of the time.
var success = 0;
var pat = /(\d{2})\/(\d{2})\/(\d{4})\s(\d{2}):(\d{2})\s(am|pm)/g;
var date = "08/01/2011 12:00 am";
for(var i=0;i<100;i++) if(pat.exec(date)) success++;
alert("success: " + success + " failed: " + (100 - success));
it alerts success: 50 failed: 50
what's going on here?
Upvotes: 2
Views: 265
Reputation: 154818
You are using the global flag. As a result, the regular expression matches only from a specific index. After each match, pat.lastIndex == 19
, then pat.lastIndex == 0
, etc.
A more trivial example:
var r = /\d/g;
r.exec("123"); // 1 - lastIndex == 0, so matching from index 0 and on
r.exec("123"); // 2 - lastIndex == 1, ditto with 1
r.exec("123"); // 3 - lastIndex == 2, ditto with 2
r.exec("123"); // null - lastIndex == 3, no matches, lastIndex is getting reset
r.exec("123"); // 1 - start all over again
Upvotes: 2
Reputation: 32468
The g
flag means that, after the first match, the second search starts at the end of the matched substring (i.e., at the end of the string), and fails, resetting the start position to the beginning of the string.
If your regular expression uses the "
g
" flag, you can use theexec
method multiple times to find successive matches in the same string. When you do so, the search starts at the substring ofstr
specified by the regular expression'slastIndex
property (test
will also advance thelastIndex
property).
from MDC docs for RexExp.exec(). (See also RegExp.lastIndex)
Upvotes: 4