Twenty
Twenty

Reputation: 5941

Matching a sequence of characters splitted by spaces after a prefix

I have the following strings:

  1. -prefix <@141222969505480701> where the second part e.g. <@141222969505480701> can be repeated unlimited times (only the numbers change).
  2. -prefix 141222969505480701 which should behave the same as above.
  3. -prefix 141222969505480701 <@141222969505480702> which would still be able to repeat itself forever.

The last one should have groups containing 141222969505480701 and 141222969505480702.

So a few bits of information:

What I tried

First of I tried to match the first of my example strings. -prefix(\s<@\d{18}>)\1* which would match the entire string, but I would like to have the digits itself in its own group. Also this method only matches the same parts e.g. <@141222969505480701> <@141222969505480701> <@141222969505480701> would match, but any other number in between wouldn't match.

What would sound logical in my head

-prefix (\d{18})+ but it would only match the first one of the 'digit parts'.

While I was testing it on regex101 it told me the following:

A repeated capturing group will only capture the last iteration. Put a capturing group around the repeated group to capture all iterations or use a non-capturing group instead if you're not interested in the data.

I tried to adjust the regex to the following -prefix ((\d{18})+), but with the same result.

Upvotes: 3

Views: 100

Answers (2)

The fourth bird
The fourth bird

Reputation: 163467

You could use an alternation to list the 3 different allowed formats. In .NET it is supported to reuse the group name.

-prefix\s*(?:(?<digits>[0-9]{18})\s*<@(?<digits>[0-9]{18})>|(?<digits>[0-9]{18})|<@(?<digits>[0-9]{18}))

Pattern parts

  • -prefix\s* Match literally followed by 0+ whitespace characters
  • (?: Non capturing group
    • (?<digits>[0-9]{18})\s*<@(?<digits>[0-9]{18})> 2 named capturing groups which will match the digits
    • | Or
    • (?<digits>[0-9]{18}) Named capturing group, match digits only
    • | Or
    • <@(?<digits>[0-9]{18}) Named capturing group, match digits between brackets only
  • )

Regex demo

enter image description here

You could also use 2 named capturing groups, 1 for each format. For example:

-prefix\s*(?:(?<digits>[0-9]{18})\s*<@(?<digitsBrackets>[0-9]{18})>|(?<digits>[0-9]{18})|<@(?<digitsBrackets>[0-9]{18}))

Regex demo

Upvotes: 0

Twenty
Twenty

Reputation: 5941

With the help to of @madreflection in the comments I was able to come up with this solution:

-prefix([\s]*(<@|)(?<digits>[0-9]{18})>?)+

Which is exactly what I needed, which even ignores spaces in between. Also with the use of match.Groups["digits"].Captures it made the whole story a lot easier.

Upvotes: 1

Related Questions