Today I came across a very strange JavaScript regular expression issue. When using the global modifier (//g), RegExp.test() yields different values in subsequent calls. Can anyone explain why?
var s = "youtube.com/watch?v=XyeebVA3DNk";
var re1 = /^youtube\.com\/watch[a-zA-Z0-9_\-\?\&\=\/]+/g;
console.log(re1.test(s)); // true
console.log(re1.test(s)); // false
console.log(re1.test(s)); // true
console.log(re1.test(s)); // false
console.log(re1.test(s)); // true
console.log(re1.test(s)); // false
console.log(re1.test(s)); // true
var re2 = /^youtube\.com\/watch[a-zA-Z0-9_\-\?\&\=\/]+/;
console.log(re2.test(s)); // true
console.log(re2.test(s)); // true
console.log(re2.test(s)); // true
console.log(re2.test(s)); // true
console.log(re2.test(s)); // true
console.log(re2.test(s)); // true
I am able to reproduce this in Chrome 8 and FireFox 3.6.
It's only when you use the g
flag. I agree it's not the best design, but the point is to let you loop over the matches, e.g. with re1.exec
.
var s = "fo1,fo2,fo3,";
var re1 = /fo\d,/g;
var match;
while(match = re1.exec(s))
{
alert(match);
}
"If your regular expression uses the "g" flag, you can use the exec method multiple times to find successive matches in the same string. When you do so, the search starts at the substring of s specified by the regular expression's lastIndex property (test will also advance the lastIndex property)."
"As with exec (or in combination with it), test called multiple times on the same global regular expression instance will advance past the previous match."
var s = "youtube.com/watch?v=XyeebVA3DNk";
var re1 = /^youtube\.com\/watch[a-zA-Z0-9_\-\?\&\=\/]+/g;
console.log(re1.test(s)); // true
var re1 = /^youtube\.com\/watch[a-zA-Z0-9_\-\?\&\=\/]+/g;
console.log(re1.test(s)); // true
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With