views:

131

answers:

2

I know there are a few regex/lastIndex discrepancies but this one is new to me!

Expected behaviour: Creating a new regular expression (with literal/constructor) will, obviously, create a new RegExp object with a lastIndex property set to zero.

Actual behaviour: (in FF, Chrome): The lastIndex property seems to persist through multiple RegExp creations.

E.g.

function foo(s) {

    // A *NEW* regular expression
    // is created on each call of foo():
    var regex = /ABC/g;

    document.write( regex.lastIndex + '<br/>' );

    // regex.test() updates lastIndex property
    regex.test(s);

    // This is where the regex's life should end...
    // (Why does it persist?)

}

foo('ABC');
foo('ABCABC');
foo('ABCABCABC');

See here: http://jsbin.com/otoze


A new RegExp object is being created on every function call (right?), so why is the following being written to the document?? -

0
3
6

???

Note, this weirdness appears to happen in FF(3) and Chrome(2), but, curiously not IE.

Is this expected behaviour, does IE get it wrong or right? Is this a well-known bug?


EDIT: this doesn't appear to happen when instantiating the regex with a constructor instead of a literal. E.g. new RegExp('ABC','g'); ... Still, the literal should (theoretically) work, right?

+4  A: 

var regex = new RegExp("ABC", "g"); doesn't have that problem, so I guess /ABC/g re-uses regexp objects.

EDIT: Apparently this is correct behavior according to the ECMAScript 3.0 specification, it's fixed in ECMAScript 3.1 - details

Lukáš Lalinský
That's my guess too... Still odd...
J-P
@J-P: It's not really that odd, you never used the `new` keyword.
Chris
What's strange is that if you call the same code in the function multiple times, it will return the correct output. It almost looks like it incorrectly optimizes out some assignments in later calls of the same function.
Lukáš Lalinský
@Chris, AFAIK, that should be implicit... That's what literals are for afterall...
J-P
@Lukas, thanks for that link! I'm glad this issue has been fixed in the ES spec.
J-P
Apparently it's a known problem in the ECMAScript specification - http://www.mail-archive.com/[email protected]/msg01796.html
Lukáš Lalinský
+1  A: 

Try this:

function foo(s) {

    // A *NEW* regular expression
    // is created on each call of foo():
    var regex = new RegEx("ABC", "g");

    document.write( regex.lastIndex + '<br/>' );

    // regex.test() updates lastIndex property
    regex.test(s);

    // This is where the regex's life should end...
    // (Why does it persist?)

}

foo('ABC');
foo('ABCABC');
foo('ABCABCABC');
Jeff B