I've encountered an issue using the regex function exec() in Firefox 10 and 11.
The function seems to behave erratic when it is called a lot. Among the correct result, it also returns null
a lot. From Safari 5.1.3, Chrome 18 and the above mentioned Firefox versions, I can see the issue only within Firefox.
I've created a JSFiddle to demonstrate the problem: / , source:
var i, x = "";
for (i = 0; i < 10000; i++) {
var matches = /foo/g.exec('sdkfjfooasdknal');
x += matches + "<br>";
}
$('body').html(x);
In my two Firefox versions, this returns 40x foo
, 1x null
, 41x foo
, and from then on it swaps between these two on every single call.
Have you encountered this?
I've encountered an issue using the regex function exec() in Firefox 10 and 11.
The function seems to behave erratic when it is called a lot. Among the correct result, it also returns null
a lot. From Safari 5.1.3, Chrome 18 and the above mentioned Firefox versions, I can see the issue only within Firefox.
I've created a JSFiddle to demonstrate the problem: http://jsfiddle/KSH3S/ , source:
var i, x = "";
for (i = 0; i < 10000; i++) {
var matches = /foo/g.exec('sdkfjfooasdknal');
x += matches + "<br>";
}
$('body').html(x);
In my two Firefox versions, this returns 40x foo
, 1x null
, 41x foo
, and from then on it swaps between these two on every single call.
Have you encountered this?
var foo = /foo/g
outside the loop)
– user166390
Commented
Apr 16, 2012 at 0:15
exec()
repeatedly on a regular expression with the "g" flag accumulates some state from one call to the next to allow you to find multiple matches in the same source string.
– jfriend00
Commented
Apr 16, 2012 at 0:18
/foo/g
constructs a new RegExp object, just as "foo"
constructs a new string object. Unless of course there is some "funny caching" going on (perhaps after the 80th such RegExp construction?). In any case, still not an explanation for erratic behavior :-)
– user166390
Commented
Apr 16, 2012 at 0:21
It's a bug in the JS engine in Firefox, like jfriend00 says. Should be fixed in Firefox 12. See https://bugzilla.mozilla/show_bug.cgi?id=728021
The problem has something to do with the implicit declaration of the regex inside the loop. My guess is that the browser is caching it somewhere or getting confused by that somehow.
If you explicitly create a new regex object each time through the for
loop, then Firefox no longer has a problem with this:
var x = "";
for (var i=0; i<10000; i++) {
var re = new RegExp("foo", "g");
var matches = re.exec( 'sdkfjfooasdknal' );
x += matches+"<br>";
}
$('body').html( x );
http://jsfiddle/jfriend00/F49db/
And, it doesn't matter which way you explicitly declare the regex as this method works also:
var x = "";
for (var i=0; i<10000; i++) {
var re = /foo/g;
var matches = re.exec( 'sdkfjfooasdknal' );
x += matches+"<br>";
}
$('body').html( x );
This is only a partial explanation. If you try this fiddle it seems to work fine. So the problem or bug might be in the regex parsing of a literal? I'm not sure, but could it be something where the loop optimization treats the literal differently than the variable.
Here is the fiddle code:
var x = "";
for (var i=0; i<10000; i++) {
var a='sdkfjfooasdknal';
var b=/foo/g;
var matches = b.exec(a);
x += matches+"<br>";
}
$('body').html( x );
UPDATE: Here is something I tried to force it out of a normal loop and the problem reappeared. Here is the fiddle http://jsfiddle/xXYdF/.
var x = "";
i=200;
function reg(){
var matches = /foo/g.exec('sdkfjfooasdknal');
x += matches+"<br>";
}
function run(){
setTimeout(function(){
if(i--){
reg();
run();
$('body').html( x );
}
},10);
}
run();