开发者

Regex in javascript fails every other time with identical input [duplicate]

This question already has answers here: Why does a RegExp with global flag give wrong results? (7 answers) Closed 6 years ago.

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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜