4

I have a paragraph like below:

Some wording for testing [!#today] where the [!condition] does not satisfy with this verbiage [!ShowElemIf://Student/FullName; [[[Text not recognized fully]]] ;/First Name] But simple tags found having age [!ShowElemIf://Student/Age;xml//Student/DOB/@formatted;y]

I need to find all the placeholders/tags from above which are like: [!tag] using C#. I tried for a regex but it is not able to find the tag having "FullName" word as highlighted in bold above.

List<string> tags = Regex.Matches(
                     sampleText.Replace(Environment.NewLine, ""), @"\[!([^]]+)\] ")
                     .Cast<Match>()
                     .Select(x => x.Groups[1].Value)
                     .ToList();

Using this RegEx I can find below but not the highlighted one.

  1. today
  2. condition
  3. ShowElemIf://Student/Age;xml//Student/DOB/@formatted;y
sapatelbaps
  • 484
  • 2
  • 8
  • 19

1 Answers1

3

You need to use balancing groups available in .NET regex:

@"\[!((?:[^][]+|(?<o>\[)|(?<-o>)])*(?(o)(?!)))]"

See the regex demo

Details:

  • \[! - a [! substring
  • ((?:[^][]+|(?<o>\[)|(?<-o>)])*(?(o)(?!))) - Capturing group 1 matching
    • (?: - a non-capturing group with 3 alternatives:
      • [^][]+| - 1 or more chars other than [ and ], or
      • (?<o>\[)| - a [ pushed into "o" group stack, or
      • (?<-o>)] - a ] is subtracted from the "o" group stack
    • )* - zero or more occurrences
    • (?(o)(?!))) - a conditional construct checking if the "o" group stack is empty. If it is empty, matching goes on, else, no match is returned.
  • ] - a literal closing ] symbol.
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563