Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find all matching regex patterns and index of the match in the string

I want to find /AA/ pattern in AA-AA-AA subject string. I need to get the matching string and the position (index) of the match.

I have looked at RegExp.prototype.exec(). It only returns the first match:

/AA/g.exec('AA-AA-AA')
like image 553
yotamoo Avatar asked May 30 '11 15:05

yotamoo


2 Answers

exec() only returns a single match. To get all matches with a g​lobal regexp, you have to call it repeatedly, eg.:

var match, indexes= [];
while (match= r.exec(value))
    indexes.push([match.index, match.index+match[0].length]);
like image 154
bobince Avatar answered Oct 22 '22 12:10

bobince


Be careful when using RegExp.prototype.exec() function to match a string. The constructed regex object is stateful, i.e. every time you call .exec() it affects the lastIndex property of the regex instance. Therefore, you should always reset the lastIndex property before using an instance of regex object.

let re,
    findAAs;

re = /AA/;

findAAs = (input) => {
    let match;

    // `re` is cached instance of regex object.
    // Reset `re.lastIndex` every time before using it.

    re.lastIndex = 0;

    while ((match = re.exec(input)) !== null) {
        match.index; // Match index.
        match[0]; // Matching string.
    }
};

A tempting alternative is to construct the regex object on every execution. Depending on how resource intensive your task is, this is an option too.

let findAAs;

findAAs = (input) => {
    let match,
        re;

    re = /AA/;

    while ((match = re.exec(input)) !== null) {
        match.index; // Match index.
        match[0]; // Matching string.
    }
};

A pragmatic alternative to using .exec() is String.prototype.replace().

let findAAs,
    re;

re = /AA/;

findAAs = (input) => {
    let match,
        re;

    input.replace(re, (match, index) => {
        match; // Matching string.
        index; // Match index.

        return '';
    });
};

The downside of this approach is that it constructs a copy of the subject string.

Whether you should use it or not, depends on how resource intensive your task is. Personally, I like to avoid while blocks in my code and therefore prefer the .replace() approach.

like image 43
Gajus Avatar answered Oct 22 '22 13:10

Gajus