Why do javascript sub-matches stop working when the g modifier is set?
var text = 'test test test test';
var result = text.match(/t(e)(s)t/);
// result: ["test", "e", "s"]
the above works fine... [1] is e and [2] is s... perfect
var result = text.match(/t(e)(s)t/g);
// ["test", "test", "test", "test"]
the above it screwed... it ignores my sub-matches
var result = text.match(/test/g);
for (i in result) {
console.log(result[i].match(/t(e)(s)t/));
}
/*
["test", "e", "s"]
["test", "e", "s"]
["test", "e", "s"]
["test", "e", "s"]
*/
is the above the only valid solution?
thanks to htw the proper way to do this would be the following:
var pattern = new RegExp(/t(e)(s)t/g);
while (match = pattern.exec(text))
{
console.log(match);
}
-
Using
String'smatch()function won't return captured groups if the global modifier is set, as you found out.In this case, you would want to use a
RegExpobject and call itsexec()function.String'smatch()is almost identical toRegExp'sexec()function…except in cases like these. If the global modifier is set, the normalmatch()function won't return captured groups, whileRegExp'sexec()function will. (Noted here, among other places.)Another catch to remember is that
exec()doesn't return the matches in one big array—it keeps returning matches until it runs out, in which case it returnsnull.So, for example, you could do something like this:
var pattern = /t(e)(s)t/g; // You could also use "new RegExp(/t(e)(s)t/g);" var match; while (match = pattern.exec(text)) { // Do something with the match (["test", "e", "s"]) here... }You can find information on how to use
RegExpobjects on W3Schools (specifically, here's the documentation for theexec()function).Chad Scira : using exec doesn't seem to listen to the g modifier, but it supports sub-matches/groups. So the result would be the first match (it basically ignores the g modifier)htw : Added a clarification about that—you have to call exec() repeatedly to get the multiple matches.Chad Scira : Not the most elegant solution. i was expecting an output somewhat like this: [ ["test", "e", "s"], ["test", "e", "s"], ["test", "e", "s"], ["test", "e", "s"] ]Shog9 : htw: good clarification. One little nit-pick: you don't really need to pass the regex literal through new RegExp().htw : @Shog9: Thanks, I forgot about that. Edited to reflect that.Chad Scira : ok very nice, its interesting that you have to do it this way. Thanks :)
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.