Click to See Complete Forum and Search --> : [RESOLVED] Inconsistencies for variables of regexp objects


johanafm
05-15-2009, 10:05 AM
When declaring variables of local scope to hold regexp objects with /g modifier, I get unexpected results. I see them as a bug, but on the other hand both Safari and FF have similar behaviour, so perhaps I'm missing something.

Every odd call to a function with local variables holding regexp objects will match, and every even call to that same function will fail the match and return null. Unless you set regexpVariable.lastIndex to 0 after declaring the variable.
Yet, with local scope that should not be necessary.

Full code shown below to illustrate the issue. Please enlighten me, because I seriously don't get this behaviour.

<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="pragma" content="no-cache" />
<meta http-equiv="cache-control" content="no-cache" />
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>Test</title>

<script type="text/javascript">
var times = 1;
function test() {
// Should yield the same result on every function call, shouldn't it?
var re = /pattern/g;
var ma = re.exec("string pattern");
alert(ma);

// This, however does yield the same result on every call
var reg = /pattern/g;
reg.lastIndex = 0;
var mat = reg.exec("string pattern");
alert(mat);

// And finally, let's make sure a variable holds something other than a regexp object
var rexp = /pattern/g;
var match = rexp.exec("string pattern");
alert(match);
rexp = new String();
// try calling rexp.exec() here. Won't work: rexp.exec is not a function (since rexp is now a string object, not a regexp object. And still, every other call to rexp.exec() fails.
}
</script>
</head>
<body style="margin: 50px;">
<input type="button" onclick="test()" value="test"/>
</body>
</html>

Weedpacket
05-16-2009, 02:55 AM
One thing is that it's a global match, which the ma object iterates through, returning each match that is found (and ending when it reaches null). Consider /p.?n/g and "pen pin pig pan". Consider also /pattern/ and "string pattern". Consider also "match" instead of "exec".

What I don't see, unfortunately, is a reason for ma's state to persist from one call of test() to the next, which is what is happening here; I would have expected the object to be local to the test method, seeing as how there's a var declaration there.

johanafm
05-31-2009, 05:58 PM
Thanks for your reply. I got an answer from a guy I met IRL, and if he remembered correctly, this behaviour is due to an older ECMA spec and should be in bugzilla. Which pretty much means the way to go for now is always setting lastIndex = 0 right after declaring and initializing the variable with a regexp object.