On inputting the following function call into chrome console:
(function(regex, str){
console.log(regex.test(str))
console.log(!regex.test(str))
console.log(! regex.test(str))
console.log( !regex.test(str))
console.log( ! regex.test(str))
})(new RegExp("new", "gmi"), "new")
I get the following results:
true
true
false
true
false
Can someone explain why the 3rd and 5th tests return false
?
And why the First and Second both return true.
You're including the "g" modifier, so the regular expression object is maintaining the state of the match progress. Each call is not the same, in other words.
Your first call matches the string "new"
, and the regex updates the position to the end of the string. The next match fails (so you see true
for !regexp.test(str)
). It fails because the string "new" does not appear at the end of the string "new".
Now we've run off the end of the string, so the next test starts over like the first. It matches again, so your !
turns that true
to false
. The one after that doesn't match, and the one after that will have started over again and it matches.
Note that the spaces around !
in the tests have absolutely nothing to do with the behavior.
edit — try this variation:
(function(regex, str){
console.log(regex.test(str) + " - " + regex.lastIndex)
console.log(!regex.test(str) + " - " + regex.lastIndex)
console.log(! regex.test(str) + " - " + regex.lastIndex)
console.log( !regex.test(str) + " - " + regex.lastIndex)
console.log( ! regex.test(str) + " - " + regex.lastIndex)
})(new RegExp("new", "gmi"), "new")
You'll see that the .lastIndex
property toggles between 0
and 3
.
I think that the moral of this story is "don't use 'g'
unless you really know you want to."
I'll explain you what's happening. Go through the comments. Its in the form of
regex.lastIndex, actual value, negated value
// code below
(function(regex, str){
console.log(regex.test(str)) // 0, true, false
console.log(!regex.test(str)) // 3, false, true => lastIndex set to 0
console.log(! regex.test(str)) // 0, true, false
console.log( !regex.test(str)) // 3, false, true => lastIndex set to 0
console.log( ! regex.test(str)) // 0, true, false
})(new RegExp("new", "gmi"), "new")
MDN
If lastIndex is equal to the length of the string and if the regular expression does not match the empty string, then the regular expression mismatches input, and lastIndex is reset to 0.
So, lastIndex
is updated in case a global regex is used more than once and it decides where to start matching.
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