Search code examples
c#regexregex-group

regex - named group only if another named group matches


A toggle command can be used as follows:

toggle
toggle n
toggle >hotspot y
toggle >hotspot
toggle @location>hotspot n
toggle @location>hotspot

my regex at the moment is the following:

^toggle(?>\s(?>@(?'location'\w+))?(?>>(?'hotspot'\w+))?)?(?>\s(?'value'n|y))?$

this one however allows the following strings to match:

toggle @location
toggle @location n

I would like to allow the named group "location" (prefixed by "@") only if the named group "hotspot" (prefixed by ">") matches.


Solution

  • In the pattern that you tried, the group hotspot should not be optional.

    There are also a few atomic groups (?> which are not necessary if you change the grouping a bit where the whitespace char can be matched optionally.

    This part n|y can also be written as a character class [ny]

    ^toggle(?:\s(?:@(?'location'\w+))?>(?'hotspot'\w+))?(?:\s(?'value'[ny]))?$
    

    Explanation

    • ^ Start of string
    • toggle Match literally
    • (?: Non capture group
      • \s Match a whitespace char
      • (?:@(?'location'\w+))? Optionally match @, capture in group location 1+ word chars
      • >(?'hotspot'\w+) Match >, capture in group hotspot 1+ word chars
    • )? Close group and make it optional
    • (?: Non capture group
      • \s(?'value'[ny]) Match a whitespace char, capture in group value either n or y
    • )? Close group and make it optional
    • $ End of string

    .NET regex demo