Search code examples
c#regexregex-group

C# Regex Atomic Opening and Closing Brackets


I have the following which is a placeholder, I'm trying to use Atomic groups to catch double opening and closing brackets in pairs:

{{(?>{{(?)|}}(<-DEPTH>)|[^{}])*}}(?(DEPTH)(?!))

I am {{name}} and I have {{scales}: red {{metallic_scales}: shiny and glistering}} scales}}

Safe to say, I'm not really having much success.

So I'd want something like:

  1. {{name}}
  2. {{scales}: red {{metallic_scales}: shiny and glistering}} scales}}
  3. {{metallic_scales}: shiny and glistering}}

Solution

  • You may use

    (?=                    # Start of a positive lookahead to enable overlapping matches
      (?<results>          # The group storing the results
        {{                 # {{ (left-hand delimiter)
          (?>              # Start of an atomic group
            (?!{{|}}).|    # Any char not starting {{ or }} char sequence, or
            {{(?<DEPTH>)|  # {{ and a value pushed on to DEPTH group stack, or
            }}(?<-DEPTH>)  # }} and a value popped from the DEPTH group stack
          )*               # Zero or more repetitions of the atomic group patterns
        }}                 # }} substring
        (?(DEPTH)(?!))     # Conditional construct failing the match if DEPTH stack is not empty
      )                    # End of the results group
    )                      # End of the lookahead
    

    See the regex demo.

    C# declaration:

    Regex reg = new Regex(@"
        (?=                  # Start of a positive lookahead to enable overlapping matches
          (?<results>          # The group storing the results
            {{                 # {{ (left-hand delimiter)
              (?>              # Start of an atomic group
                (?!{{|}}).|    # Any char not starting {{ or }} char sequence, or
                {{(?<DEPTH>)|  # {{ and a value pushed on to DEPTH group stack, or
                }}(?<-DEPTH>)  # }} and a value popped from the DEPTH group stack
              )*               # Zero or more repetitions of the atomic group patterns
            }}                 # }} substring
            (?(DEPTH)(?!))     # Conditional construct failing the match if DEPTH stack is not empty
          )                    # End of the results group
        )                      # End of the lookahead", 
        RegexOptions.IgnorePatternWhitespace | RegexOptions.Singleline);
    var results = reg.Matches(text).Cast<Match>().Select(x => x.Groups["results"].Value);