Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it preferred to use methods on RegExp objects or String objects?

Tags:

javascript

There are regex matching methods on both RegExp objects and String objects in Javascript.

RegExp objects have the methods

  • exec
  • test

String objects have the methods

  • match
  • search

The exec and match methods are very similar:

/word/.exec("words");
//Result: ["word"]
"words".match(/word/);
//Result: ["word"]

/word/.exec("No match");
//Result: null
"No match".match(/word/);
//Result: null

/word/g.exec("word word");
//Result: ["word"]
"word word".match(/word/g);
//Result: ["word", "word"]

and the test and search are also very similar:

/word/.test("words");
//Result: true
"words".search(/word/);
//Result: 0
//Which can converted to a boolean:
"word".search(/word/) > -1;
//Result: true

/word/.test("No match");
//Result: false
"No match".search(/word/) > -1;
//Result: false

Is there a preference to use the methods on RegExp objects or on String objects?

like image 965
Digital Plane Avatar asked Sep 08 '11 21:09

Digital Plane


2 Answers

Mostly Personal Preference

This is mostly personal preference, though there is a slight difference in capabilities (see last paragraph for that difference). Unless you want to start benchmarking performance measurements and turn the question into one of performance, it's mostly personal preference.

I prefer to do:

string.match(/word/)

because I think that makes the code read like my brain thinks of the operation. I'm taking the string object and looking for a particular regular expression in it. It makes sense to me that looking for something in a string is a method on the string object. This reads to me like:

object.action(tool)

which is how object oriented code should work in my opinion.

If you have:

/word/.match(string)

then to me it feels like:

tool.action(object)

which I find a lot less logical and less object-oriented. Yes, /word/ is technically an object too, but it's not the object I'm trying to operate on, I think of it more like a tool or a parameter I'm using with my object.

Obviously both work. You can decide for yourself which you like.

One Major Difference

There are a few things that I believe you can only do on a regular expression object. For example, if you want to match all occurrences of a regular expression, you have to create the regular expression object, pass it the "g" option and then call re.exec() multiple times to get each match until exec returns null indicating no more matches. I don't think you can do that with string.match().

like image 129
jfriend00 Avatar answered Nov 18 '22 09:11

jfriend00


There are some differences between match and exec when using the global flag g. You can't loop through global occourences with match, while using exec you can:

var string="xabx xnnx";
var regexp=new RegExp('x([^x]*)x','g');

// match returns the list of matching parts:
string.match(regexp) // ["xabx", "xnnx"]

// with exec you could build a loop:
var match=regexp.exec(string);
while (match) {
    console.log(match);
    match=regexp.exec(string);
}
// This loops through matches and returns subpatterns too:
// ["xabx", "ab"]
// ["xnnx", "nn"]

And index doesn't work at all when using match with a globalized RegExp object:

var r=/b/g;
r.exec("0123b56b").index // 4
r.exec("0123b56b").index // 7
"0123b56b".match(r).index // undefined
"0123b56b".match(/b/).index // 4
like image 2
amoebe Avatar answered Nov 18 '22 09:11

amoebe