Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

regex.test() only works every other time

Regex test() is giving me issues in Firefox and Chrome, yet it works flawlessly in Opera and Safari.

troubled code:

var pattern = /(\s+(?!\$\w+)|(^(?!\$\w+)))/g;
if(pattern.test(String(id).replace(/\s+OR|AND\s+/g, ''))) {
 searchError("You suck.");
 return 1;
}

When you pass in white space, it blocks it every time. When you pass in something like '$a b' then it will work every other time in Firefox/Chrome. WEIRD.

like image 356
Jacksonkr Avatar asked Oct 08 '10 14:10

Jacksonkr


People also ask

How does regex test work?

JavaScript RegExp test() The test() method tests for a match in a string. If it finds a match, it returns true, otherwise it returns false.

What is $1 in regex replace?

For example, the replacement pattern $1 indicates that the matched substring is to be replaced by the first captured group.

How do you test expressions in regex?

To test a regular expression, first search for errors such as non-escaped characters or unbalanced parentheses. Then test it against various input strings to ensure it accepts correct strings and regex wrong ones. A regex tester tool is a great tool that does all of this.

What does the G flag do regex?

The g flag indicates that the regular expression should be tested against all possible matches in a string. A regular expression defined as both global ( g ) and sticky ( y ) will ignore the global flag and perform sticky matches.


2 Answers

It's a bug in the RegEx engine, a similar question with the same issue came up here.

From my answer to that question: It's a bug with the way regexes are implemented in ECMAScript 3, there's a great post on the details here.

The basics are a /regex/ with the g modifier doesn't reset correctly, so multiple .test() calls alternate between true and false if everyone should be true, every other calls successfully resets it.

like image 168
Nick Craver Avatar answered Oct 08 '22 20:10

Nick Craver


This seems to still be an issue in August of 2021... I just want to share some things I have learned before stumbling upon this question and answer. I was baffled by this problem and had no meaningful way forward - until now.

  1. It doesn't matter whether you use exec() or test() or match(). The regex still doesn't work properly on every other occurrence.

  2. It doesn't matter if you set the regex with

let reg = new RegExp(/<table(\s*[^>]*)>/g); 

or with const. Doesn't matter if you set it globally or locally either...

What does work to bypass this problem is wrapping your regex statement in parenthesis in your loop like so:

Object.keys(table).forEach(key => {     if((new RegExp(/<table(\s*[^>]*)>/g)).test(___your test string___)){         //Do what you need to do     } }); 

Remove the parenthesis around the Regex, and watch every other one fail....

Thank you so much for the answer @Nick Craver and the comment @prototype!

This exact Regex was what was giving me trouble. It would work for one object, and fail for the subsequent object, and it made no sense. I am only here to say that this is still very relevant in 2021.

like image 36
Willie Avatar answered Oct 08 '22 22:10

Willie