Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between RegExp constructor and Regex literal test function? [duplicate]

I'm confused on how this is possible...

var matcher = new RegExp("d", "gi");
matcher.test(item)

The code above contains the following values

item = "Douglas Enas"
matcher = /d/gi

Yet when I run the matcher.test function back to back I get true for the first run and false for the second run.

matcher.test(item) // true
matcher.test(item) // false

If I use a regexp literal such as

/d/gi.test("Douglas Enas") 

and run it back to back in chrome I get true both times. Is there an explanation for this?

Sample of a back to back run in chrome console creating a regexp object using constructor

matcher = new RegExp("d","gi")
/d/gi

matcher.test("Douglas Enas")
true

matcher.test("Douglas Enas")
false

matcher
/d/gi

Sample using back to back calls on literal

/d/gi.test("Douglas Enas")
true

/d/gi.test("Douglas Enas")
true

The reason for this question if because using the RegExp constructor and the test function against a list of values I'm losing matches... However using the literal I'm getting back all the values I expect

UPDATE

                        var suggestions = [];

                        ////process response  
                        $.each(responseData, function (i, val)
                        {
                            suggestions.push(val.desc);
                        });


                        var arr = $.grep(suggestions, function(item) {
                            var matcher = new RegExp("d", "gi");
                            return matcher.test(item);
                        });

Moving the creation of the matcher inside the closure included the missing results. the "d" is actually a dynamically created string but I used "d" for simplicity sake. I'm still not sure now creating a new expression every time I do the test when I am iterating over the suggestions array would inadvertently exclude results is a little confusing still, and probably has something to do with the advancement of the match test

like image 478
DRobertE Avatar asked Nov 21 '12 19:11

DRobertE


People also ask

What is RegEx constructor?

The RegExp constructor creates a regular expression object for matching text with a pattern. For an introduction to regular expressions, read the Regular Expressions chapter in the JavaScript Guide.

What does New RegExp do in JavaScript?

The expression new RegExp(/ab+c/, flags) will create a new RegExp using the source of the first parameter and the flags provided by the second. When using the constructor function, the normal string escape rules (preceding special characters with \ when included in a string) are necessary.

What is GI in RegEx?

The gi modifier is used to do a case insensitive search of all occurrences of a regular expression in a string.


Video Answer


1 Answers

From RegExp.test():

test called multiple times on the same global regular expression instance will advance past the previous match.

So basically when you have an instance of RegExp, each call to test advances the matcher. Once you've found the first d, it will look beyond that and try to find another d. Well, there are none anymore, so it returns false.

On the other hand, when you do:

/d/gi.test("Douglas Enas") 

You create a new RegExp instance every time on the spot, so it will always find that first d (and thus return true).

like image 52
NullUserException Avatar answered Oct 23 '22 17:10

NullUserException