0
votes

I feel like this should be very simple, and I'm missing a single, important bit.

Example: https://regex101.com/r/lXh5Vj/1

Regex, using /m/g flags:

^GROUPS.*?"(?<name>[^:]+):(?<id>\d+)"

Test string:

GROUPS: ["group1:44343", "group2:23324", "group3:66567"]
USERS: ["user1:44343", "user2:23324", "user3:66567"]

My current regex will only match group1, because only that group is directly preceded by "GROUPS". I interpret this as "Global matching" meaning it will only start to check the string again after the first match. As there is no "GROUPS" between group1 and group2, group2 is not a match. If I alter the test string and add "GROUPS" before group2, this will also match, supporting my suspicion. But I do not know how to alter global matching handling to always consider the start of the line GROUPS.

The Regex should match 3 and 3 in the first line, and none in the second. If I remove the "GROUPS" part from the regex, the groups are matched just fine, but then also match the second line, which I do not want.

1
What about multiple matches with (?:\G(?!\A)|^GROUPS).*?"\K(?<name>[^:]+):(?<id>\d+)"? See demo.Wiktor Stribiżew
Or with the square brackets (?:^GROUPS[^"]*\[(?=[^][]*])"|\G(?!^))(?<name>[^:]+):(?<id>\d+)" regex101.com/r/aBQvKu/1The fourth bird
Please provide answers as answers, not comments :) . Wiktor: Your solution works great! The fourth bird: Your solution matches the ", " before the groupnames as well, so not ideal.Senshi
@Senshi Yea the posted answer is a different one. I will remove the comment.The fourth bird

1 Answers

1
votes

If you want to match GROUPS: [" at the start of the string, and the key:value parts in named groups, you can make use of the \G anchor.

(?:^GROUPS:\h*\["(?=[^][]*])|\G(?!^),\h*")(?<name>[^:]+):(?<id>\d+)"
  • (?: Non capture group
    • ^GROUPS:\h*\[ Start of string, Match GROUPS: optional spaces and [
    • "(?=[^][]*]) Match " and assert a closing ] at the right
    • | Or
    • \G(?!^),\h*" Assert the position at the end of the previous match (to get consecutive groups) and match a comma, optional spaces and "
  • ) Close non capture group
  • (?<name>[^:]+) Named group name Match 1+ times any char except :
  • : Match literally
  • (?<id>\d+) Named group id, match 1+ digits
  • " Match literally

Regex demo