1

How do I get all successive matches for groups selector in regular expresion? All matches (not just first) means I need to use global flag (/g) but with global flag it is not possible to get groups in result array via myString.match() or RegExp.exec(myString). Both functions are useless for this situation because of combination global flag and groups returns just first match.

For example I have myString = 'Lorem Ipsum group-a-1 blah group-b-1 dummy simply text of the printing group-a-2 blah group-b-2 and typesetting industry' and I would like to get all occurences for group-a-* and group-b-* pairs.


I can match whoole parts with groups using first RegExp and then I need to use second RegExp (but without global flag) to get group(s). Used myString.match():

var matchesOne = myString.match(/(group-a-[0-9]) blah (group-b-[0-9])/gi); // ["group-a-1 blah group-b-1", "group-a-2 blah group-b-2"]
for (var i = 0; i < matchesOne.length; i++) {
    var matchesTwo = matchesOne[i].match(/(group-a-[0-9]) blah (group-b-[0-9])/i); // note missing global flag here
    console.log("WHOLE: " + matchesTwo[0] + ";", "GROUP-A: " + matchesTwo[1] + ";", "GROUP-B: " + matchesTwo[2] + ";");
}
// Result:
// WHOLE: group-a-1 blah group-b-1; GROUP-A: group-a-1; GROUP-B: group-b-1;
// WHOLE: group-a-2 blah group-b-2; GROUP-A: group-a-2; GROUP-B: group-b-2;

Developer mozilla recommends similar solution using while cycle. Used RegExp.exec(myString):

var matches, myRegExp = /(group-a-[0-9]) blah (group-b-[0-9])/gi;
while ((matches = myRegExp.exec(myString)) !== null) {
    console.log("WHOLE: " + matches[0] + ";", "GROUP-A: " + matches[1] + ";", "GROUP-B: " + matches[2] + ";");
}
// Result:
// WHOLE: group-a-1 blah group-b-1; GROUP-A: group-a-1; GROUP-B: group-b-1;
// WHOLE: group-a-2 blah group-b-2; GROUP-A: group-a-2; GROUP-B: group-b-2;

Both solutions require running RegExp multiple times in cycle. But I would like to use easy one command/function such as preg_match_all() do in php. Is it possible?

mikep
  • 5,880
  • 2
  • 30
  • 37

1 Answers1

2

Most elegant solution seems to be myString.replace() which will replace nothing (I ignore returned value) but helps to easily get whole matched part and its groups. Data are clearly stored in separate variables instead of abstract numerically indexed array.

myString.replace(/(group-a-[0-9]) blah (group-b-[0-9])/gi, function(whole, groupA, groupB) {
    console.log("WHOLE: " + whole + ";", "GROUP-A: " + groupA + ";", "GROUP-B: " + groupB + ";");
});
// Result:
// WHOLE: group-a-1 blah group-b-1; GROUP-A: group-a-1; GROUP-B: group-b-1;
// WHOLE: group-a-2 blah group-b-2; GROUP-A: group-a-2; GROUP-B: group-b-2;
mikep
  • 5,880
  • 2
  • 30
  • 37
  • You can use snippets to make the result looks even better – Thomas Ayoub Oct 19 '16 at 07:56
  • In stackoverflow.com/a/983827/3832970 accepted answer does not handle groups and another answer uses solution which requires repeating RegExp in cycle. This is about one-line/one-command solution with executing only one RegExp. – mikep Oct 19 '16 at 08:12