One of the nice things that many people don’t know about JavaScript String replace() function is the fact that the second parameter can either be a string or a callback function. This callback function receives the entire matched substring, each parenthesized group (if not found the empty string is passed), the index of the match within the original string, and the original string. You can actually get these values using the String match() function, but this doesn’t work for retrieving these values for each instance of a globally matched regular expression. In this case, one could use the following code to define a matchAll() function:


String.prototype.matchAll = function(regexp) {
  var matches = [];
  this.replace(regexp, function() {
    var arr = ([]).slice.call(arguments, 0);
    var extras = arr.splice(-2);
    arr.index = extras[0];
    arr.input = extras[1];
    matches.push(arr);
  });
  return matches.length ? matches : null;
};

If a global regular expression is passed to the function defined above, an array of arrays similar to those that come from the native match() will be returned. As occurs with the native match() function, each sub-array will have an index property and an input property. The index property indicates the position where this particular match began in the original string. The input property indicates the string that the matches were found in.

The following is an example of running this function:


var str = 'Hello world!!!';
var regexp = /(\w+)\W*/g;
console.log(str.matchAll(regexp));

An array containing two arrays will be generated:


[
  {
    0: "Hello ",
    1: "Hello"
    index: 0,
    input: "Hello world!!!"
  },
  {
    0: "world!!!",
    1: "world"
    index: 6,
    input: "Hello world!!!"
  }
]

Even though the sub-arrays above are really object literals, the arrays that come back from this matchAll() function will be true arrays with those two properties (index and input) set for each. Hopefully this helps. 8)


3 Comments

Eben · January 3, 2015 at 5:40 PM

Hi Chris,

Thank you, this is very useful. I’ve used this twice so far in my code, the first time I was under a tight deadline and this saved me a lot of time.

Eben

Isaac Lopez · February 1, 2015 at 7:00 PM

Thanks Chris ,

this snippet save my day

Nirav · September 22, 2020 at 11:04 AM

Thankyou very very very much you help a lot to me

Leave a Reply

Your email address will not be published. Required fields are marked *