reesaspieces
reesaspieces

Reputation: 1810

regex.exec(str) works but str.matchAll(regex) doesn't

I'm trying to use an regex to capture all of the tags in a query string like below (in this case, horror and comedy). There may be more or less than two tags; this is just an example.

const queryString = "?q=user:bob tag:horror tag:comedy"

const grabTagsRegex = new RegExp(/.* tag:(.+)( |$)/g)

I can get the first matched group like this:

const result = grabTagsRegex.exec(queryString)
// result[1] gives me "horror"

But I would like to capture all of the tags, so I looked into using matchAll like this, but it returned an empty RegExpStringIterator.

queryString.matchAll(grabTagsRegex)

I'd like to know how to get all the tags so I can iterate over them. I've looked at SO threads like this one but couldn't get it to work. I'm suspecting that my regex is not correct but I'm not sure.

Thanks for any help in advance.

Upvotes: 1

Views: 117

Answers (1)

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 627317

Your pattern is rather wrong since .* tag:(.+)( |$) matches the last occurrence of the " tag:" substring and captures any one or more chars other than line break chars as many as possible to the right of the current location, and that means the end of string here.

You can use

queryString.matchAll(/\btag:(\S+)/g)

Here, \btag:(\S+) matches a tag as a whole word with : on the right, and then captures any one or more non-whitespace chars into Group 1.

See the regex demo and the JavaScript demo:

const queryString = "?q=user:bob tag:horror tag:comedy";
const matches = queryString.matchAll(/\btag:(\S+)/g);
console.log(Array.from(matches, x => x[1]));

Upvotes: 2

Related Questions