RegExp.test() with global flag set

M

Matt

Hello all,

I have just discovered (the long way) that using a RegExp object with
the 'global' flag set produces inconsistent results when its test()
method is executed. I realize that 'global' is not an appropriate
modifier for the test() function - test() searches the entire string
by default.

However, I would expect it to degrade gracefully. Instead, I seem to
be getting something as follows - using W3Schools handy page at [1]:

Input:
-----------------------------------------------
<html>
<body>

<script type="text/javascript">
var patt = new RegExp('3','g');
document.write("Regex.test() inconsistencies: <br>")
for (var i=0; i<10; i++) {
if (patt.test("12345")==true) {
document.write("pass<br>")
} else {
document.write("fail<br>")
}
}

</script>
</body>
</html>

Output:
-----------------------------------------------
Regex.test() inconsistencies:
pass
fail
pass
fail
pass
fail
pass
fail
pass
fail

If you remove the 'g' modifier on the RegExp object, all of the tests
pass as you would expect. This happens on all current major browsers.
Seems like a bug to me, albeit with a fairly simply workaround. I
haven't found it reported anywhere else though - is my diagnosis
correct, and if so where does one go to report such things?

Thanks,
Matt.

[1] http://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_compile_regexp
 
T

Thomas 'PointedEars' Lahn

Matt said:
I have just discovered (the long way) that using a RegExp object with
the 'global' flag set produces inconsistent results when its test()
method is executed. I realize that 'global' is not an appropriate
modifier for the test() function - test() searches the entire string
by default.

However, I would expect it to degrade gracefully. Instead, I seem to
be getting something as follows - using W3Schools handy page at [1]:

RegExp.prototype.test() works as designed, and W3Schools is more of a curse
than suitable reference material. Proof for both follows below, again.

The test case is not even Valid markup to begin with.

<script type="text/javascript">
var patt = new RegExp('3','g');

One wonders why you did not use the more efficient RegExp initializer here,
supported since JavaScript 1.2 (Netscape 3.0), JScript 3.0 (MSHTML 4.0).
Maybe because of W3Schools babbling nonsense about how to "compile regexp"?

var patt = /3/g;
document.write("Regex.test() inconsistencies: <br>")
for (var i=0; i<10; i++) {
if (patt.test("12345")==true) {

W3Schools nonsense as well: The method returns a boolean value already, so
omitting `==true' is equivalent and more efficient. That goes for almost
all comparisons with boolean values in almost all programming languages.
document.write("pass<br>")
} else {
document.write("fail<br>")
}

And again. In fact, this can be rewritten much more efficient as

document.write((patt.test("12345") ? "pass": "fail") + "<br>");

Note the trailing semicolon which is indicative of good coding style, not
relying on automatic semicolon insertion and risking the side-effects
thereof. That isn't something you can find in W3Schools code, of course.
}

</script>
</body>
</html>

Output:
-----------------------------------------------
Regex.test() inconsistencies:
pass
fail
[...]

If you remove the 'g' modifier on the RegExp object, all of the tests
pass as you would expect. This happens on all current major browsers.

And then it did not occur to you to try applying Occam's Razor which would
mean that all the "major browsers" (whatever those might be) are correct and
only your reasoning is not?
Seems like a bug to me, [...]

If only you had read the (ECMAScript) Specification(, Edition 3 Final)
before complaining:

| 15.10.6.2 RegExp.prototype.exec(string)
| [...]
|
| 15.10.6.3 RegExp.prototype.test(string)
|
| Equivalent to the expression RegExp.prototype.exec(string) != null.

The second call of RegExp.prototype.test() on that expression MUST return
`false' in a conforming implementation because there are no more matches for
the global-flagged regular expression, and RegExp.prototype.exec() would
therefore return `null'. That is also why the next call MUST return `true'
again as the matching index is reset and RegExp.prototype.exec() would not
return `null' (since there was a match), and why removing the `g' modifier
makes a difference.


PointedEars
 
D

dhtml

Matt said:
Hello all,

I have just discovered (the long way) that using a RegExp object with
the 'global' flag set produces inconsistent results when its test()
method is executed. I realize that 'global' is not an appropriate
modifier for the test() function - test() searches the entire string
by default.


Props to you for doing your research and asking a simple question with
actual code.

You just didn't find the right answer or maybe didn't know where to
look. Let me guess: You probably searched google and got w3schools at
teh top result page. (I know I always see w3schools on the first page).

Well now you have your answer.

Cheers,

Garrett

 
M

Matt

Props to you for doing your research and asking a simple question with
actual code.

You just didn't find the right answer or maybe didn't know where to
look. Let me guess: You probably searched google and got w3schools at
teh top result page. (I know I always see w3schools on the first page).

Thank you gents.

My mistake was not realising that the RegExp object maintained state,
and that subsequent calls to a non-globally matching RegExp.exec()
would return the next match rather than just the first one again.

As for W3Schools - actually I just knew about their 'try it now'
pages, which seemed to be a quick and easy way for me to explore the
issue and y'all to test it simply. My apologies if it wasn't efficient
enough for some of you.

Cheers,
Matt.
 
T

Thomas 'PointedEars' Lahn

Matt said:
Thank you gents.

You are welcome.
My mistake was not realising that the RegExp object maintained state,
Yes.

and that subsequent calls to a non-globally matching RegExp.exec()
would return the next match rather than just the first one again.

That would be correct had you omitted the "non-" :)
As for W3Schools - actually I just knew about their 'try it now'
pages, which seemed to be a quick and easy way for me to explore the
issue and y'all to test it simply. My apologies if it wasn't efficient
enough for some of you.

As I have showed, lack of efficiency is only one of its problems.


PointedEars

P.S.
When trimming quotations, please do not remove attribution lines for
quotations that you leave in.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,077
Latest member
SangMoor21

Latest Threads

Top