Regex in javascript fails every other time with identical input [duplicate]
A simple test script:
<script type="text/javascript">
var reg = new RegExp('#([a-f0-9]{3})$', 'gi');
for (var i = 0; i < 10; i++) {
console.log(reg.exec('#fff'));
}
</script>
Console output:
["#fff", "fff"]
null
["#fff", "fff"]
null
["#fff", "fff"]
null
["开发者_如何学Go#fff", "fff"]
null
["#fff", "fff"]
null
Why is every other result null when the input remains constant?
When you use the global flag, the regex becomes "sticky." That is to say, it uses a counter variable to track where the last match was found. Rather than matching from the beginning each time, a sticky regex will actually pick up where the last match ended. This counter will only reset back to 0 (the beginning) if the entire match fails (which is why it works every-other-time)
In your case, my suggestion would be to drop the g
flag.
For more information: RegExp @ MDC
Matt has answered why. I just wanted to add that you can see this by checking the value of lastIndex
on the RegExp
object before and after the exec
call
var reg = new RegExp('#([a-f0-9]{3})$', 'gi');
for (var i = 0; i < 10; i++) {
console.log(reg.lastIndex);
console.log(reg.exec('#fff'));
console.log(reg.lastIndex);
}
output is
0
["#fff", "fff"]
4
4
null
0
0
["#fff", "fff"]
4
4
null
0
0
["#fff", "fff"]
4
4
null
0
0
["#fff", "fff"]
4
4
null
0
0
["#fff", "fff"]
4
4
null
0
undefined
demonstrating that on every other iteration of the loop, the regex matching is starting from where the lastIndex
finished. You could set lastIndex
to 0 before each exec
call or drop the flag altogether.
Your problem is the "gi"
in the second argument, I just removed it and tested on the Chrome console:
var reg = new RegExp('#([a-f0-9]{3})$');
I found this on the web...
Calling the exec() function also changes the
lastIndex
property of the RegExp object.
It stores the index in the subject string at which the next match attempt will begin.
You can modify this value to change the starting position of the next call to exec().
The behavior you describe indicates that the RegExp
object has a state that is modified by calling the exec() method.
I think you need to modify the lastindex
property before you re-run the exec method.
read more here: Javascript Regexp Object
精彩评论