Reputation: 6720
I am looking for an effective way to create array contain all matches contains regex groups matches.
e.g. Regex /(1)(2)(3)/g
string 123
expected result ['1','2','3']
My current code looks like this:
var matches = [];
value.replace(fPattern, function (a, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15) {
for(var i = 1, v; i < 15; i++){
v = eval('s' + i);
if(v){
matches.push(v);
}else{
break;
}
}
});
It works, however I don't like the way how it does.
The first thing is that I actually don't know how many groups I will have in my regex variable fPattern
so I need to define a lot unnecessary variables s1, s2 ... etc
.
The second problem Is that I decided to use evil eval
to prevent pushing this variables 'manually' one by one to array, maybe there is a better solution?
And one more thing - I did try use match()
but unfortunately when I have pattern /(1)(2)(3)/g
it will return me array ['123']
so it's not what I want to achieve.
Thanks!
EDIT
Ok I found something which looks better
matches = fPattern.exec(value);
if(matches && matches.length){
for(var key in matches){
if(key !== '0'){
if(key !== 'index'){
formated += matches[key] + ' ';
}else{
break;
}
}
};
}
Upvotes: 0
Views: 54
Reputation: 4431
A less stateful / more functional solution might be something like this:
function findInString(string, pattern) {
return string.split('').filter(function (element) {
return element.match(pattern)
})
}
Takes in a string to search through and regex literal, returns an array of the matched elements. So, for example:
var foo = '123asfasff111f6';
findInString(foo, /\d/g)
will return [ '1', '2', '3', '1', '1', '1', '6' ]
, which seems to be what you're looking for(?).(at least, based on the below)
e.g. Regex /(1)(2)(3)/g string 123 expected result ['1','2','3']
You can pass in whatever regex literal you want and it should act on every item in the array and return it if matched. I'd go with something like this if you want to easily be able to reason about state/might have to re-use it later to match a different pattern. The question was a little fuzzy for me, so your exact needs might be slightly different -- tried to go off what your expected inputs and outputs were.
Upvotes: 1
Reputation: 56809
Use RegExp.exec
and collect its return values, which consist of the main match, the capturing groups and the starting index of the main match.
function findall(re, input) {
// Match only once for non global regex
// You are free to modify the code to turn on the global flag
// and turn it off before return
if (!re.global) {
return input.match(re);
} else {
re.lastIndex = 0;
}
var arr;
var out = [];
while ((arr = re.exec(input)) != null) {
delete arr.input; // Don't need this
out.push(arr);
// Empty string match. Need to advance lastIndex
if (arr[0].length == 0) {
re.lastIndex++;
}
}
return out;
}
Upvotes: 1
Reputation: 26667
Something like
arrays = "123".match(/(1)(2)(3)/);
arrays.splice(0,1);
console.log(arrays);
=> Array [ "1", "2", "3" ]
The match
returns an array where the array index 0
will contain the entire match. From array index 1
onwards it will contain the value of corresponding capture group.
arrays.splice(0,1);
would remove the index 0
element, the entire match from the array, The resulting array will only contain teh capture group values
Upvotes: 1