JS: How to combine one capture group multiple times in one line?
Situation
I have a string that I want to map multiple times to the same capture group. I need to be able to get both matches.
Sample code
var curly = new RegExp("{([a-z0-9]+)}", "gi");
var stringTest = "This is a {test} of my {pattern}";
var matched = curly.exec(stringTest);
console.log(matched);
Problem
Now it only shows the first match, not the second.
JSFiddle Link
source to share
Try the following:
var curly = /{([a-z0-9]+)}/gi,
stringTest = "This is a {test} of my {pattern}",
matched;
while(matched = curly.exec(stringTest))
console.log(matched);
source to share
The exec method should be used in a while loop if you want to process multiple results. See MDN documentation .
source to share
Strings in JavaScript have a method match
- you can use this to match all regex instances returned as an array:
stringTest.match(curly);
This will return an array of matches:
> ["{test}", "{pattern}"]
To pull out the internal values, you can use substr
:
var arr = stringTest.match(curly);
arr[0] = arr[0].substr(1, arr[0].length - 2);
> "test"
Or to convert the entire array:
for (var i = 0; i < arr.length; i++)
arr[i] = arr[i].substr(1, arr[i].length - 2);
> ["test", "pattern"]
source to share
This is usually done by a method RegExp.exec
but you know it's confusing. Every time I need to use this, I have to look up to remember this stateful operation. It's like you need a state monad or something :)
Anyway. The latest JS engines have this one that does the same thing in a very sane way , returning an iterator object. String.matchAll()
String.matchAll()
var curly = new RegExp("{([a-z0-9]+)}", "gi");
var stringTest = "This is a {test} of my {pattern}";
var matches = [...stringTest.matchAll(curly)];
console.log(matches);
If you only want capture groups, just match the above result. Let's use Array.from()
this time.
var curly = new RegExp("{([a-z0-9]+)}", "gi");
var stringTest = "This is a {test} of my {pattern}";
var matches = Array.from(stringTest.matchAll(curly), m => m[1]);
console.log(matches);
source to share