Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript string.match refuses to return an array of more than one match

I have a string that I expect to be formatted like so:

{List:[Names:a,b,c][Ages:1,2,3]}

My query looks like this in javascript:

var str = "{List:[Names:a,b,c][Ages:1,2,3]}";
var result = str.match(/^\{List:\[Names:([a-zA-z,]*)\]\[Ages:([0-9,]*)\]\}$/g);

Note: I recognize that with this regex it would pass with something like "Ages:,,,", but I'm not worried about that at the moment.

I was expecting to get this back:

result[0] = "{List:[Names:a,b,c][Ages:1,2,3]}"
result[1] = "a,b,c"
result[2] = "1,2,3"

But no matter what I seem to do to the regular expression, it refuses to return an array of more than one match, I just get the full string back (because it passes, which is a start):

result = ["{List:[Names:a,b,c][Ages:1,2,3]}"]

I've looked through a bunch of questions on here already, as well as other 'intro' articles, and none of them seem to address something this basic. I'm sure it's something foolish that I've overlooked, but I truly have no idea what it is :(

like image 282
a.real.human.being Avatar asked Oct 29 '25 14:10

a.real.human.being


2 Answers

So this is a difference in how the global flag is applied in Regular Expressions in JavaScript.

In .match, the global flag (/g at the end) will return an array of every incident where the regular expression matches the string. Without that flag, .match will return an array of all of the groupings in the string.

eg:

var str = "{List:[Names:a,b,c][Ages:1,2,3]}";
str += str;
// removed ^ and $ for demonstration purposes
var results = str.match(/\{List:\[Names:([a-zA-z,]*)\]\[Ages:([0-9,]*)\]\}/g)
console.log(results)
// ["{List:[Names:a,b,c][Ages:1,2,3]}", "{List:[Names:a,b,c][Ages:1,2,3]}"]
str = "{List:[Names:a,b,c][Ages:1,2,3]}{List:[Names:a,b,c][Ages:3,4,5]}";
results = str.match(/\{List:\[Names:([a-zA-z,]*)\]\[Ages:([0-9,]*)\]\}/g);
console.log(results)
//["{List:[Names:a,b,c][Ages:1,2,3]}", "{List:[Names:a,b,c][Ages:3,4,5]}"]

Now, if we remove that /g flag:

// leaving str as above
results = str.match(/\{List:\[Names:([a-zA-z,]*)\]\[Ages:([0-9,]*)\]\}/);
console.log(results)
//["{List:[Names:a,b,c][Ages:1,2,3]}", "a,b,c", "1,2,3"]

And as a note as to why regex.exec worked, that is because:

If the regular expression does not include the g flag, returns the same result as regexp.exec(string).

like image 122
cwallenpoole Avatar answered Oct 31 '25 08:10

cwallenpoole


You're looking for the form needle.exec(haystack)

From my console:

> haystack = "{List:[Names:a,b,c][Ages:1,2,3]}";
"{List:[Names:a,b,c][Ages:1,2,3]}"

> needle = /^\{List:\[Names:([a-zA-z,]*)\]\[Ages:([0-9,]*)\]\}$/g ;
/^\{List:\[Names:([a-zA-z,]*)\]\[Ages:([0-9,]*)\]\}$/g

> needle.exec(haystack);
["{List:[Names:a,b,c][Ages:1,2,3]}", "a,b,c", "1,2,3"]
like image 31
FrankieTheKneeMan Avatar answered Oct 31 '25 08:10

FrankieTheKneeMan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!