[javascript] How do you access the matched groups in a JavaScript regular expression?

I want to match a portion of a string using a regular expression and then access that parenthesized substring:

var myString = "something format_abc"; // I want "abc"

var arr = /(?:^|\s)format_(.*?)(?:\s|$)/.exec(myString);

console.log(arr);     // Prints: [" format_abc", "abc"] .. so far so good.
console.log(arr[1]);  // Prints: undefined  (???)
console.log(arr[0]);  // Prints: format_undefined (!!!)

What am I doing wrong?


I've discovered that there was nothing wrong with the regular expression code above: the actual string which I was testing against was this:

"date format_%A"

Reporting that "%A" is undefined seems a very strange behaviour, but it is not directly related to this question, so I've opened a new one, Why is a matched substring returning "undefined" in JavaScript?.


The issue was that console.log takes its parameters like a printf statement, and since the string I was logging ("%A") had a special value, it was trying to find the value of the next parameter.

This question is related to javascript regex

The answer is


JUST USE RegExp.$1...$n th group eg:

1.To match 1st group RegExp.$1

  1. To match 2nd group RegExp.$2

if you use 3 group in regex likey(note use after string.match(regex))

RegExp.$1 RegExp.$2 RegExp.$3

_x000D_
_x000D_
 var str = "The rain in ${india} stays safe"; _x000D_
  var res = str.match(/\${(.*?)\}/ig);_x000D_
  //i used only one group in above example so RegExp.$1_x000D_
console.log(RegExp.$1)
_x000D_
_x000D_
_x000D_

_x000D_
_x000D_
//easiest way is use RegExp.$1 1st group in regex and 2nd grounp like_x000D_
 //RegExp.$2 if exist use after match_x000D_
_x000D_
var regex=/\${(.*?)\}/ig;_x000D_
var str = "The rain in ${SPAIN} stays ${mainly} in the plain"; _x000D_
  var res = str.match(regex);_x000D_
for (const match of res) {_x000D_
  var res = match.match(regex);_x000D_
  console.log(match);_x000D_
  console.log(RegExp.$1)_x000D_
 _x000D_
}
_x000D_
_x000D_
_x000D_


Get all group occurrence

_x000D_
_x000D_
let m=[], s = "something format_abc  format_def  format_ghi";_x000D_
_x000D_
s.replace(/(?:^|\s)format_(.*?)(?:\s|$)/g, (x,y)=> m.push(y));_x000D_
_x000D_
console.log(m);
_x000D_
_x000D_
_x000D_


Using your code:

console.log(arr[1]);  // prints: abc
console.log(arr[0]);  // prints:  format_abc

Edit: Safari 3, if it matters.


We can access the matched group in a regular expressions by using backslash followed by number of the matching group:

/([a-z])\1/

In the code \1 represented matched by first group ([a-z])


With es2018 you can now String.match() with named groups, makes your regex more explicit of what it was trying to do.

const url =
  'https://stackoverflow.com/questions/432493/how-do-you-access-the-matched-groups-in-a-javascript-regular-expression?some=parameter';
const regex = /(?<protocol>https?):\/\/(?<hostname>[\w-\.]*)\/(?<pathname>[\w-\./]+)\??(?<querystring>.*?)?$/;
const { groups: segments } = url.match(regex);
console.log(segments);

and you'll get something like

{protocol: "https", hostname: "stackoverflow.com", pathname: "questions/432493/how-do-you-access-the-matched-groups-in-a-javascript-regular-expression", querystring: "some=parameter"}


Your syntax probably isn't the best to keep. FF/Gecko defines RegExp as an extension of Function.
(FF2 went as far as typeof(/pattern/) == 'function')

It seems this is specific to FF -- IE, Opera, and Chrome all throw exceptions for it.

Instead, use either method previously mentioned by others: RegExp#exec or String#match.
They offer the same results:

var regex = /(?:^|\s)format_(.*?)(?:\s|$)/;
var input = "something format_abc";

regex(input);        //=> [" format_abc", "abc"]
regex.exec(input);   //=> [" format_abc", "abc"]
input.match(regex);  //=> [" format_abc", "abc"]

You don't really need an explicit loop to parse multiple matches — pass a replacement function as the second argument as described in: String.prototype.replace(regex, func):

_x000D_
_x000D_
var str = "Our chief weapon is {1}, {0} and {2}!"; _x000D_
var params= ['surprise', 'fear', 'ruthless efficiency'];_x000D_
var patt = /{([^}]+)}/g;_x000D_
_x000D_
str=str.replace(patt, function(m0, m1, position){return params[parseInt(m1)];});_x000D_
_x000D_
document.write(str);
_x000D_
_x000D_
_x000D_

The m0 argument represents the full matched substring {0}, {1}, etc. m1 represents the first matching group, i.e. the part enclosed in brackets in the regex which is 0 for the first match. And position is the starting index within the string where the matching group was found — unused in this case.


Last but not least, I found one line of code that worked fine for me (JS ES6):

_x000D_
_x000D_
let reg = /#([\S]+)/igm; // Get hashtags._x000D_
let string = 'mi alegría es total! ?\n#fiestasdefindeaño #PadreHijo #buenosmomentos #france #paris';_x000D_
_x000D_
let matches = (string.match(reg) || []).map(e => e.replace(reg, '$1'));_x000D_
console.log(matches);
_x000D_
_x000D_
_x000D_

This will return:

['fiestasdefindeaño', 'PadreHijo', 'buenosmomentos', 'france', 'paris']

Your syntax probably isn't the best to keep. FF/Gecko defines RegExp as an extension of Function.
(FF2 went as far as typeof(/pattern/) == 'function')

It seems this is specific to FF -- IE, Opera, and Chrome all throw exceptions for it.

Instead, use either method previously mentioned by others: RegExp#exec or String#match.
They offer the same results:

var regex = /(?:^|\s)format_(.*?)(?:\s|$)/;
var input = "something format_abc";

regex(input);        //=> [" format_abc", "abc"]
regex.exec(input);   //=> [" format_abc", "abc"]
input.match(regex);  //=> [" format_abc", "abc"]

Last but not least, I found one line of code that worked fine for me (JS ES6):

_x000D_
_x000D_
let reg = /#([\S]+)/igm; // Get hashtags._x000D_
let string = 'mi alegría es total! ?\n#fiestasdefindeaño #PadreHijo #buenosmomentos #france #paris';_x000D_
_x000D_
let matches = (string.match(reg) || []).map(e => e.replace(reg, '$1'));_x000D_
console.log(matches);
_x000D_
_x000D_
_x000D_

This will return:

['fiestasdefindeaño', 'PadreHijo', 'buenosmomentos', 'france', 'paris']

/*Regex function for extracting object from "window.location.search" string.
 */

var search = "?a=3&b=4&c=7"; // Example search string

var getSearchObj = function (searchString) {

    var match, key, value, obj = {};
    var pattern = /(\w+)=(\w+)/g;
    var search = searchString.substr(1); // Remove '?'

    while (match = pattern.exec(search)) {
        obj[match[0].split('=')[0]] = match[0].split('=')[1];
    }

    return obj;

};

console.log(getSearchObj(search));

Your code works for me (FF3 on Mac) even if I agree with PhiLo that the regex should probably be:

/\bformat_(.*?)\b/

(But, of course, I'm not sure because I don't know the context of the regex.)


Here’s a method you can use to get the n?th capturing group for each match:

_x000D_
_x000D_
function getMatches(string, regex, index) {_x000D_
  index || (index = 1); // default to the first capturing group_x000D_
  var matches = [];_x000D_
  var match;_x000D_
  while (match = regex.exec(string)) {_x000D_
    matches.push(match[index]);_x000D_
  }_x000D_
  return matches;_x000D_
}_x000D_
_x000D_
_x000D_
// Example :_x000D_
var myString = 'something format_abc something format_def something format_ghi';_x000D_
var myRegEx = /(?:^|\s)format_(.*?)(?:\s|$)/g;_x000D_
_x000D_
// Get an array containing the first capturing group for every match_x000D_
var matches = getMatches(myString, myRegEx, 1);_x000D_
_x000D_
// Log results_x000D_
document.write(matches.length + ' matches found: ' + JSON.stringify(matches))_x000D_
console.log(matches);
_x000D_
_x000D_
_x000D_


_x000D_
_x000D_
var myString = "something format_abc";_x000D_
var arr = myString.match(/\bformat_(.*?)\b/);_x000D_
console.log(arr[0] + " " + arr[1]);
_x000D_
_x000D_
_x000D_

The \b isn't exactly the same thing. (It works on --format_foo/, but doesn't work on format_a_b) But I wanted to show an alternative to your expression, which is fine. Of course, the match call is the important thing.


Using your code:

console.log(arr[1]);  // prints: abc
console.log(arr[0]);  // prints:  format_abc

Edit: Safari 3, if it matters.


Your code works for me (FF3 on Mac) even if I agree with PhiLo that the regex should probably be:

/\bformat_(.*?)\b/

(But, of course, I'm not sure because I don't know the context of the regex.)


As @cms said in ECMAScript (ECMA-262) you can use matchAll. It return an iterator and by putting it in [... ] (spread operator) it converts to an array.(this regex extract urls of file names)

_x000D_
_x000D_
let text = `<a href="http://myhost.com/myfile_01.mp4">File1</a> <a href="http://myhost.com/myfile_02.mp4">File2</a>`;

let fileUrls = [...text.matchAll(/href="(http\:\/\/[^"]+\.\w{3})\"/g)].map(r => r[1]);

console.log(fileUrls);
_x000D_
_x000D_
_x000D_


In regards to the multi-match parentheses examples above, I was looking for an answer here after not getting what I wanted from:

var matches = mystring.match(/(?:neededToMatchButNotWantedInResult)(matchWanted)/igm);

After looking at the slightly convoluted function calls with while and .push() above, it dawned on me that the problem can be solved very elegantly with mystring.replace() instead (the replacing is NOT the point, and isn't even done, the CLEAN, built-in recursive function call option for the second parameter is!):

var yourstring = 'something format_abc something format_def something format_ghi';

var matches = [];
yourstring.replace(/format_([^\s]+)/igm, function(m, p1){ matches.push(p1); } );

After this, I don't think I'm ever going to use .match() for hardly anything ever again.


Terminology used in this answer:

  • Match indicates the result of running your RegEx pattern against your string like so: someString.match(regexPattern).
  • Matched patterns indicate all matched portions of the input string, which all reside inside the match array. These are all instances of your pattern inside the input string.
  • Matched groups indicate all groups to catch, defined in the RegEx pattern. (The patterns inside parentheses, like so: /format_(.*?)/g, where (.*?) would be a matched group.) These reside within matched patterns.

Description

To get access to the matched groups, in each of the matched patterns, you need a function or something similar to iterate over the match. There are a number of ways you can do this, as many of the other answers show. Most other answers use a while loop to iterate over all matched patterns, but I think we all know the potential dangers with that approach. It is necessary to match against a new RegExp() instead of just the pattern itself, which only got mentioned in a comment. This is because the .exec() method behaves similar to a generator functionit stops every time there is a match, but keeps its .lastIndex to continue from there on the next .exec() call.

Code examples

Below is an example of a function searchString which returns an Array of all matched patterns, where each match is an Array with all the containing matched groups. Instead of using a while loop, I have provided examples using both the Array.prototype.map() function as well as a more performant way – using a plain for-loop.

Concise versions (less code, more syntactic sugar)

These are less performant since they basically implement a forEach-loop instead of the faster for-loop.

// Concise ES6/ES2015 syntax
const searchString = 
    (string, pattern) => 
        string
        .match(new RegExp(pattern.source, pattern.flags))
        .map(match => 
            new RegExp(pattern.source, pattern.flags)
            .exec(match));

// Or if you will, with ES5 syntax
function searchString(string, pattern) {
    return string
        .match(new RegExp(pattern.source, pattern.flags))
        .map(match =>
            new RegExp(pattern.source, pattern.flags)
            .exec(match));
}

let string = "something format_abc",
    pattern = /(?:^|\s)format_(.*?)(?:\s|$)/;

let result = searchString(string, pattern);
// [[" format_abc", "abc"], null]
// The trailing `null` disappears if you add the `global` flag

Performant versions (more code, less syntactic sugar)

// Performant ES6/ES2015 syntax
const searchString = (string, pattern) => {
    let result = [];

    const matches = string.match(new RegExp(pattern.source, pattern.flags));

    for (let i = 0; i < matches.length; i++) {
        result.push(new RegExp(pattern.source, pattern.flags).exec(matches[i]));
    }

    return result;
};

// Same thing, but with ES5 syntax
function searchString(string, pattern) {
    var result = [];

    var matches = string.match(new RegExp(pattern.source, pattern.flags));

    for (var i = 0; i < matches.length; i++) {
        result.push(new RegExp(pattern.source, pattern.flags).exec(matches[i]));
    }

    return result;
}

let string = "something format_abc",
    pattern = /(?:^|\s)format_(.*?)(?:\s|$)/;

let result = searchString(string, pattern);
// [[" format_abc", "abc"], null]
// The trailing `null` disappears if you add the `global` flag

I have yet to compare these alternatives to the ones previously mentioned in the other answers, but I doubt this approach is less performant and less fail-safe than the others.


One line solution:

const matches = (text,regex) => [...text.matchAll(regex)].map(([match])=>match)

So you can use this way (must use /g):

matches("something format_abc", /(?:^|\s)format_(.*?)(?:\s|$)/g)

result:

[" format_abc"]

As @cms said in ECMAScript (ECMA-262) you can use matchAll. It return an iterator and by putting it in [... ] (spread operator) it converts to an array.(this regex extract urls of file names)

_x000D_
_x000D_
let text = `<a href="http://myhost.com/myfile_01.mp4">File1</a> <a href="http://myhost.com/myfile_02.mp4">File2</a>`;

let fileUrls = [...text.matchAll(/href="(http\:\/\/[^"]+\.\w{3})\"/g)].map(r => r[1]);

console.log(fileUrls);
_x000D_
_x000D_
_x000D_


There is no need to invoke the exec method! You can use "match" method directly on the string. Just don't forget the parentheses.

var str = "This is cool";
var matches = str.match(/(This is)( cool)$/);
console.log( JSON.stringify(matches) ); // will print ["This is cool","This is"," cool"] or something like that...

Position 0 has a string with all the results. Position 1 has the first match represented by parentheses, and position 2 has the second match isolated in your parentheses. Nested parentheses are tricky, so beware!


In regards to the multi-match parentheses examples above, I was looking for an answer here after not getting what I wanted from:

var matches = mystring.match(/(?:neededToMatchButNotWantedInResult)(matchWanted)/igm);

After looking at the slightly convoluted function calls with while and .push() above, it dawned on me that the problem can be solved very elegantly with mystring.replace() instead (the replacing is NOT the point, and isn't even done, the CLEAN, built-in recursive function call option for the second parameter is!):

var yourstring = 'something format_abc something format_def something format_ghi';

var matches = [];
yourstring.replace(/format_([^\s]+)/igm, function(m, p1){ matches.push(p1); } );

After this, I don't think I'm ever going to use .match() for hardly anything ever again.


We can access the matched group in a regular expressions by using backslash followed by number of the matching group:

/([a-z])\1/

In the code \1 represented matched by first group ([a-z])


_x000D_
_x000D_
function getMatches(string, regex, index) {_x000D_
  index || (index = 1); // default to the first capturing group_x000D_
  var matches = [];_x000D_
  var match;_x000D_
  while (match = regex.exec(string)) {_x000D_
    matches.push(match[index]);_x000D_
  }_x000D_
  return matches;_x000D_
}_x000D_
_x000D_
_x000D_
// Example :_x000D_
var myString = 'Rs.200 is Debited to A/c ...2031 on 02-12-14 20:05:49 (Clear Bal Rs.66248.77) AT ATM. TollFree 1800223344 18001024455 (6am-10pm)';_x000D_
var myRegEx = /clear bal.+?(\d+\.?\d{2})/gi;_x000D_
_x000D_
// Get an array containing the first capturing group for every match_x000D_
var matches = getMatches(myString, myRegEx, 1);_x000D_
_x000D_
// Log results_x000D_
document.write(matches.length + ' matches found: ' + JSON.stringify(matches))_x000D_
console.log(matches);
_x000D_
_x000D_
_x000D_

_x000D_
_x000D_
function getMatches(string, regex, index) {_x000D_
  index || (index = 1); // default to the first capturing group_x000D_
  var matches = [];_x000D_
  var match;_x000D_
  while (match = regex.exec(string)) {_x000D_
    matches.push(match[index]);_x000D_
  }_x000D_
  return matches;_x000D_
}_x000D_
_x000D_
_x000D_
// Example :_x000D_
var myString = 'something format_abc something format_def something format_ghi';_x000D_
var myRegEx = /(?:^|\s)format_(.*?)(?:\s|$)/g;_x000D_
_x000D_
// Get an array containing the first capturing group for every match_x000D_
var matches = getMatches(myString, myRegEx, 1);_x000D_
_x000D_
// Log results_x000D_
document.write(matches.length + ' matches found: ' + JSON.stringify(matches))_x000D_
console.log(matches);
_x000D_
_x000D_
_x000D_


String#matchAll (see the Stage 3 Draft / December 7, 2018 proposal), simplifies acccess to all groups in the match object (mind that Group 0 is the whole match, while further groups correspond to the capturing groups in the pattern):

With matchAll available, you can avoid the while loop and exec with /g... Instead, by using matchAll, you get back an iterator which you can use with the more convenient for...of, array spread, or Array.from() constructs

This method yields a similar output to Regex.Matches in C#, re.finditer in Python, preg_match_all in PHP.

See a JS demo (tested in Google Chrome 73.0.3683.67 (official build), beta (64-bit)):

_x000D_
_x000D_
var myString = "key1:value1, key2-value2!!@key3=value3";_x000D_
var matches = myString.matchAll(/(\w+)[:=-](\w+)/g);_x000D_
console.log([...matches]); // All match with capturing group values
_x000D_
_x000D_
_x000D_

The console.log([...matches]) shows

enter image description here

You may also get match value or specific group values using

_x000D_
_x000D_
let matchData = "key1:value1, key2-value2!!@key3=value3".matchAll(/(\w+)[:=-](\w+)/g)_x000D_
var matches = [...matchData]; // Note matchAll result is not re-iterable_x000D_
_x000D_
console.log(Array.from(matches, m => m[0])); // All match (Group 0) values_x000D_
// => [ "key1:value1", "key2-value2", "key3=value3" ]_x000D_
console.log(Array.from(matches, m => m[1])); // All match (Group 1) values_x000D_
// => [ "key1", "key2", "key3" ]
_x000D_
_x000D_
_x000D_

NOTE: See the browser compatibility details.


A one liner that is practical only if you have a single pair of parenthesis:

while ( ( match = myRegex.exec( myStr ) ) && matches.push( match[1] ) ) {};

_x000D_
_x000D_
var myString = "something format_abc";_x000D_
var arr = myString.match(/\bformat_(.*?)\b/);_x000D_
console.log(arr[0] + " " + arr[1]);
_x000D_
_x000D_
_x000D_

The \b isn't exactly the same thing. (It works on --format_foo/, but doesn't work on format_a_b) But I wanted to show an alternative to your expression, which is fine. Of course, the match call is the important thing.


Your syntax probably isn't the best to keep. FF/Gecko defines RegExp as an extension of Function.
(FF2 went as far as typeof(/pattern/) == 'function')

It seems this is specific to FF -- IE, Opera, and Chrome all throw exceptions for it.

Instead, use either method previously mentioned by others: RegExp#exec or String#match.
They offer the same results:

var regex = /(?:^|\s)format_(.*?)(?:\s|$)/;
var input = "something format_abc";

regex(input);        //=> [" format_abc", "abc"]
regex.exec(input);   //=> [" format_abc", "abc"]
input.match(regex);  //=> [" format_abc", "abc"]

Here’s a method you can use to get the n?th capturing group for each match:

_x000D_
_x000D_
function getMatches(string, regex, index) {_x000D_
  index || (index = 1); // default to the first capturing group_x000D_
  var matches = [];_x000D_
  var match;_x000D_
  while (match = regex.exec(string)) {_x000D_
    matches.push(match[index]);_x000D_
  }_x000D_
  return matches;_x000D_
}_x000D_
_x000D_
_x000D_
// Example :_x000D_
var myString = 'something format_abc something format_def something format_ghi';_x000D_
var myRegEx = /(?:^|\s)format_(.*?)(?:\s|$)/g;_x000D_
_x000D_
// Get an array containing the first capturing group for every match_x000D_
var matches = getMatches(myString, myRegEx, 1);_x000D_
_x000D_
// Log results_x000D_
document.write(matches.length + ' matches found: ' + JSON.stringify(matches))_x000D_
console.log(matches);
_x000D_
_x000D_
_x000D_


_x000D_
_x000D_
var myString = "something format_abc";_x000D_
var arr = myString.match(/\bformat_(.*?)\b/);_x000D_
console.log(arr[0] + " " + arr[1]);
_x000D_
_x000D_
_x000D_

The \b isn't exactly the same thing. (It works on --format_foo/, but doesn't work on format_a_b) But I wanted to show an alternative to your expression, which is fine. Of course, the match call is the important thing.


Terminology used in this answer:

  • Match indicates the result of running your RegEx pattern against your string like so: someString.match(regexPattern).
  • Matched patterns indicate all matched portions of the input string, which all reside inside the match array. These are all instances of your pattern inside the input string.
  • Matched groups indicate all groups to catch, defined in the RegEx pattern. (The patterns inside parentheses, like so: /format_(.*?)/g, where (.*?) would be a matched group.) These reside within matched patterns.

Description

To get access to the matched groups, in each of the matched patterns, you need a function or something similar to iterate over the match. There are a number of ways you can do this, as many of the other answers show. Most other answers use a while loop to iterate over all matched patterns, but I think we all know the potential dangers with that approach. It is necessary to match against a new RegExp() instead of just the pattern itself, which only got mentioned in a comment. This is because the .exec() method behaves similar to a generator functionit stops every time there is a match, but keeps its .lastIndex to continue from there on the next .exec() call.

Code examples

Below is an example of a function searchString which returns an Array of all matched patterns, where each match is an Array with all the containing matched groups. Instead of using a while loop, I have provided examples using both the Array.prototype.map() function as well as a more performant way – using a plain for-loop.

Concise versions (less code, more syntactic sugar)

These are less performant since they basically implement a forEach-loop instead of the faster for-loop.

// Concise ES6/ES2015 syntax
const searchString = 
    (string, pattern) => 
        string
        .match(new RegExp(pattern.source, pattern.flags))
        .map(match => 
            new RegExp(pattern.source, pattern.flags)
            .exec(match));

// Or if you will, with ES5 syntax
function searchString(string, pattern) {
    return string
        .match(new RegExp(pattern.source, pattern.flags))
        .map(match =>
            new RegExp(pattern.source, pattern.flags)
            .exec(match));
}

let string = "something format_abc",
    pattern = /(?:^|\s)format_(.*?)(?:\s|$)/;

let result = searchString(string, pattern);
// [[" format_abc", "abc"], null]
// The trailing `null` disappears if you add the `global` flag

Performant versions (more code, less syntactic sugar)

// Performant ES6/ES2015 syntax
const searchString = (string, pattern) => {
    let result = [];

    const matches = string.match(new RegExp(pattern.source, pattern.flags));

    for (let i = 0; i < matches.length; i++) {
        result.push(new RegExp(pattern.source, pattern.flags).exec(matches[i]));
    }

    return result;
};

// Same thing, but with ES5 syntax
function searchString(string, pattern) {
    var result = [];

    var matches = string.match(new RegExp(pattern.source, pattern.flags));

    for (var i = 0; i < matches.length; i++) {
        result.push(new RegExp(pattern.source, pattern.flags).exec(matches[i]));
    }

    return result;
}

let string = "something format_abc",
    pattern = /(?:^|\s)format_(.*?)(?:\s|$)/;

let result = searchString(string, pattern);
// [[" format_abc", "abc"], null]
// The trailing `null` disappears if you add the `global` flag

I have yet to compare these alternatives to the ones previously mentioned in the other answers, but I doubt this approach is less performant and less fail-safe than the others.


Using your code:

console.log(arr[1]);  // prints: abc
console.log(arr[0]);  // prints:  format_abc

Edit: Safari 3, if it matters.


_x000D_
_x000D_
function getMatches(string, regex, index) {_x000D_
  index || (index = 1); // default to the first capturing group_x000D_
  var matches = [];_x000D_
  var match;_x000D_
  while (match = regex.exec(string)) {_x000D_
    matches.push(match[index]);_x000D_
  }_x000D_
  return matches;_x000D_
}_x000D_
_x000D_
_x000D_
// Example :_x000D_
var myString = 'Rs.200 is Debited to A/c ...2031 on 02-12-14 20:05:49 (Clear Bal Rs.66248.77) AT ATM. TollFree 1800223344 18001024455 (6am-10pm)';_x000D_
var myRegEx = /clear bal.+?(\d+\.?\d{2})/gi;_x000D_
_x000D_
// Get an array containing the first capturing group for every match_x000D_
var matches = getMatches(myString, myRegEx, 1);_x000D_
_x000D_
// Log results_x000D_
document.write(matches.length + ' matches found: ' + JSON.stringify(matches))_x000D_
console.log(matches);
_x000D_
_x000D_
_x000D_

_x000D_
_x000D_
function getMatches(string, regex, index) {_x000D_
  index || (index = 1); // default to the first capturing group_x000D_
  var matches = [];_x000D_
  var match;_x000D_
  while (match = regex.exec(string)) {_x000D_
    matches.push(match[index]);_x000D_
  }_x000D_
  return matches;_x000D_
}_x000D_
_x000D_
_x000D_
// Example :_x000D_
var myString = 'something format_abc something format_def something format_ghi';_x000D_
var myRegEx = /(?:^|\s)format_(.*?)(?:\s|$)/g;_x000D_
_x000D_
// Get an array containing the first capturing group for every match_x000D_
var matches = getMatches(myString, myRegEx, 1);_x000D_
_x000D_
// Log results_x000D_
document.write(matches.length + ' matches found: ' + JSON.stringify(matches))_x000D_
console.log(matches);
_x000D_
_x000D_
_x000D_


Your code works for me (FF3 on Mac) even if I agree with PhiLo that the regex should probably be:

/\bformat_(.*?)\b/

(But, of course, I'm not sure because I don't know the context of the regex.)


A one liner that is practical only if you have a single pair of parenthesis:

while ( ( match = myRegex.exec( myStr ) ) && matches.push( match[1] ) ) {};

_x000D_
_x000D_
var myString = "something format_abc";_x000D_
var arr = myString.match(/\bformat_(.*?)\b/);_x000D_
console.log(arr[0] + " " + arr[1]);
_x000D_
_x000D_
_x000D_

The \b isn't exactly the same thing. (It works on --format_foo/, but doesn't work on format_a_b) But I wanted to show an alternative to your expression, which is fine. Of course, the match call is the important thing.


I you are like me and wish regex would return an Object like this:

{
    match: '...',
    matchAtIndex: 0,
    capturedGroups: [ '...', '...' ]
}

then snip the function from below

_x000D_
_x000D_
/**_x000D_
 * @param {string | number} input_x000D_
 *          The input string to match_x000D_
 * @param {regex | string}  expression_x000D_
 *          Regular expression _x000D_
 * @param {string} flags_x000D_
 *          Optional Flags_x000D_
 * _x000D_
 * @returns {array}_x000D_
 * [{_x000D_
    match: '...',_x000D_
    matchAtIndex: 0,_x000D_
    capturedGroups: [ '...', '...' ]_x000D_
  }]     _x000D_
 */_x000D_
function regexMatch(input, expression, flags = "g") {_x000D_
  let regex = expression instanceof RegExp ? expression : new RegExp(expression, flags)_x000D_
  let matches = input.matchAll(regex)_x000D_
  matches = [...matches]_x000D_
  return matches.map(item => {_x000D_
    return {_x000D_
      match: item[0],_x000D_
      matchAtIndex: item.index,_x000D_
      capturedGroups: item.length > 1 ? item.slice(1) : undefined_x000D_
    }_x000D_
  })_x000D_
}_x000D_
_x000D_
let input = "key1:value1, key2:value2 "_x000D_
let regex = /(\w+):(\w+)/g_x000D_
_x000D_
let matches = regexMatch(input, regex)_x000D_
_x000D_
console.log(matches)
_x000D_
_x000D_
_x000D_


You don't really need an explicit loop to parse multiple matches — pass a replacement function as the second argument as described in: String.prototype.replace(regex, func):

_x000D_
_x000D_
var str = "Our chief weapon is {1}, {0} and {2}!"; _x000D_
var params= ['surprise', 'fear', 'ruthless efficiency'];_x000D_
var patt = /{([^}]+)}/g;_x000D_
_x000D_
str=str.replace(patt, function(m0, m1, position){return params[parseInt(m1)];});_x000D_
_x000D_
document.write(str);
_x000D_
_x000D_
_x000D_

The m0 argument represents the full matched substring {0}, {1}, etc. m1 represents the first matching group, i.e. the part enclosed in brackets in the regex which is 0 for the first match. And position is the starting index within the string where the matching group was found — unused in this case.


There is no need to invoke the exec method! You can use "match" method directly on the string. Just don't forget the parentheses.

var str = "This is cool";
var matches = str.match(/(This is)( cool)$/);
console.log( JSON.stringify(matches) ); // will print ["This is cool","This is"," cool"] or something like that...

Position 0 has a string with all the results. Position 1 has the first match represented by parentheses, and position 2 has the second match isolated in your parentheses. Nested parentheses are tricky, so beware!


/*Regex function for extracting object from "window.location.search" string.
 */

var search = "?a=3&b=4&c=7"; // Example search string

var getSearchObj = function (searchString) {

    var match, key, value, obj = {};
    var pattern = /(\w+)=(\w+)/g;
    var search = searchString.substr(1); // Remove '?'

    while (match = pattern.exec(search)) {
        obj[match[0].split('=')[0]] = match[0].split('=')[1];
    }

    return obj;

};

console.log(getSearchObj(search));

With es2018 you can now String.match() with named groups, makes your regex more explicit of what it was trying to do.

const url =
  'https://stackoverflow.com/questions/432493/how-do-you-access-the-matched-groups-in-a-javascript-regular-expression?some=parameter';
const regex = /(?<protocol>https?):\/\/(?<hostname>[\w-\.]*)\/(?<pathname>[\w-\./]+)\??(?<querystring>.*?)?$/;
const { groups: segments } = url.match(regex);
console.log(segments);

and you'll get something like

{protocol: "https", hostname: "stackoverflow.com", pathname: "questions/432493/how-do-you-access-the-matched-groups-in-a-javascript-regular-expression", querystring: "some=parameter"}


String#matchAll (see the Stage 3 Draft / December 7, 2018 proposal), simplifies acccess to all groups in the match object (mind that Group 0 is the whole match, while further groups correspond to the capturing groups in the pattern):

With matchAll available, you can avoid the while loop and exec with /g... Instead, by using matchAll, you get back an iterator which you can use with the more convenient for...of, array spread, or Array.from() constructs

This method yields a similar output to Regex.Matches in C#, re.finditer in Python, preg_match_all in PHP.

See a JS demo (tested in Google Chrome 73.0.3683.67 (official build), beta (64-bit)):

_x000D_
_x000D_
var myString = "key1:value1, key2-value2!!@key3=value3";_x000D_
var matches = myString.matchAll(/(\w+)[:=-](\w+)/g);_x000D_
console.log([...matches]); // All match with capturing group values
_x000D_
_x000D_
_x000D_

The console.log([...matches]) shows

enter image description here

You may also get match value or specific group values using

_x000D_
_x000D_
let matchData = "key1:value1, key2-value2!!@key3=value3".matchAll(/(\w+)[:=-](\w+)/g)_x000D_
var matches = [...matchData]; // Note matchAll result is not re-iterable_x000D_
_x000D_
console.log(Array.from(matches, m => m[0])); // All match (Group 0) values_x000D_
// => [ "key1:value1", "key2-value2", "key3=value3" ]_x000D_
console.log(Array.from(matches, m => m[1])); // All match (Group 1) values_x000D_
// => [ "key1", "key2", "key3" ]
_x000D_
_x000D_
_x000D_

NOTE: See the browser compatibility details.


Get all group occurrence

_x000D_
_x000D_
let m=[], s = "something format_abc  format_def  format_ghi";_x000D_
_x000D_
s.replace(/(?:^|\s)format_(.*?)(?:\s|$)/g, (x,y)=> m.push(y));_x000D_
_x000D_
console.log(m);
_x000D_
_x000D_
_x000D_


Using your code:

console.log(arr[1]);  // prints: abc
console.log(arr[0]);  // prints:  format_abc

Edit: Safari 3, if it matters.


I you are like me and wish regex would return an Object like this:

{
    match: '...',
    matchAtIndex: 0,
    capturedGroups: [ '...', '...' ]
}

then snip the function from below

_x000D_
_x000D_
/**_x000D_
 * @param {string | number} input_x000D_
 *          The input string to match_x000D_
 * @param {regex | string}  expression_x000D_
 *          Regular expression _x000D_
 * @param {string} flags_x000D_
 *          Optional Flags_x000D_
 * _x000D_
 * @returns {array}_x000D_
 * [{_x000D_
    match: '...',_x000D_
    matchAtIndex: 0,_x000D_
    capturedGroups: [ '...', '...' ]_x000D_
  }]     _x000D_
 */_x000D_
function regexMatch(input, expression, flags = "g") {_x000D_
  let regex = expression instanceof RegExp ? expression : new RegExp(expression, flags)_x000D_
  let matches = input.matchAll(regex)_x000D_
  matches = [...matches]_x000D_
  return matches.map(item => {_x000D_
    return {_x000D_
      match: item[0],_x000D_
      matchAtIndex: item.index,_x000D_
      capturedGroups: item.length > 1 ? item.slice(1) : undefined_x000D_
    }_x000D_
  })_x000D_
}_x000D_
_x000D_
let input = "key1:value1, key2:value2 "_x000D_
let regex = /(\w+):(\w+)/g_x000D_
_x000D_
let matches = regexMatch(input, regex)_x000D_
_x000D_
console.log(matches)
_x000D_
_x000D_
_x000D_