Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bug with RegExp.test (JavaScript)

I found in my code funny issue. Here is simplified version of my code. Calling regex.test changes its output value each time you call that. You can try to do that in devtools with 'evaluation on select' and it will show you different values.

like image 781
IC_ Avatar asked May 07 '17 04:05

IC_


People also ask

What is RegExp test in JavaScript?

The RegExp test() Method in JavaScript is used to test for match in a string. If there is a match this method returns true else it returns false. Where str is the string to be searched. This is required field.

Which is faster RegExp match or RegExp test?

Use . test if you want a faster boolean check. Use . match to retrieve all matches when using the g global flag.

How do you check if a string matches a regex?

If you need to know if a string matches a regular expression RegExp , use RegExp.prototype.test() . If you only want the first match found, you might want to use RegExp.prototype.exec() instead.

Does regex work in JavaScript?

In JavaScript, you can write RegExp patterns using simple patterns, special characters, and flags. In this section, we'll explore the different ways to write regular expressions while focusing on simple patterns, special characters, and flags.


1 Answers

The issue is that you are using /g in your Regexp - when this is used, and the regex is executed multiple times, it will always begin where it left off last time.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/lastIndex

This property is set only if the regular expression instance used the "g" flag to indicate a global search. The following rules apply:

If lastIndex is greater than the length of the string, test() and exec() fail, then lastIndex is set to 0.

If lastIndex is equal to the length of the string and if the regular expression matches the empty string, then the regular expression matches input starting at lastIndex.

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.

Otherwise, lastIndex is set to the next position following the most recent match.

You can verify this by doing console.log(regex.lastIndex) in your loop:

for (var a = 0; a < 10; a++) {
    console.log(regex.lastIndex)
    if (!regex.test(inner)) {
        log.innerHTML += "true";
    }
    else {
        log.innerHTML += "false";
    }

    log.innerHTML += " ";
}

And you will see it alternates between 0 18. So, when it starts at 0, it matches, when it starts at 18, it doesn't match.

like image 113
dave Avatar answered Oct 10 '22 06:10

dave