Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JS regex skips every other match

I'm seeing some strange behavior with a RegExp object in JS. I'm attempting to match a query string against the beginnings of words for a search autocomplete function. While iterating over an array of names and returning the matches, the regex only hits on every other expected match.

var words = [
                "catherine",
                "caterpillar", 
                "nice catch", 
                "fat cat", 
                "catalina"
            ],
            re = new RegExp('\\bcat', 'gi'),
            matches = [],
            results, i;

for (i=0; i<words.length; i++) {
    if (re.exec(words[i])) {
        matches.push(words[i]);
    }
}

console.log(matches);

This code returns ["catherine", "nice catch", "catalina"]. Behavior is the same no matter what order the elements are in. If I re-create this RegExp object in every iteration (e.g. re = new RegExp('\\bcat', 'gi') inside the for loop), it works as expected and returns all the array items, but I'd really rather not have to do that for every pass.

I'm not too familiar with regular expressions - is this a problem with my regex? Did I forget a delimiter or something? Or is it just another JS quirk?

like image 615
arizzitano Avatar asked Feb 19 '23 10:02

arizzitano


2 Answers

When you call exec on a RegExp object it maintains a lastIndex property that contains the previous index at which your regex matched the string. The next time you attempt to match using exec it will only start looking at index lastIndex + 1, even if you are searching in a different string.

To prevent this, you can set re.lastIndex to -1 on each iteration of the loop, or just drop the global flag when creating the RegExp.

like image 114
Andrew Clark Avatar answered Feb 21 '23 23:02

Andrew Clark


Javascript quirk. :P

http://www.w3schools.com/jsref/jsref_regexp_g.asp

like image 24
napolux Avatar answered Feb 22 '23 01:02

napolux