Search code examples
.netregexbnf

How can I transform this Backus–Naur Form expression into a Regex (.Net)?


The expression is:

N | ( 1 { A | B | C | D | E1 | E2 | E3 } )

Meaning the descriptor "N" or one or more of the listed descriptors without repetition.

The best I have got is:

@"^(N|(A|B|C|D|E1|E2|E3){1,})$"

But that does not prevent repetition.

@"^(N|(A{0,1}B{0,1}...)$" 

That prevents repetition but then requires a specific order to the elements, which isn't really OK either.

Any ideas?

(I am not actually sure that the bnf expression itself disallows repetition, but that is what I need.)


Solution

  • Well, you can, but it ain't pretty:

    Regex regexObj = new Regex(
        @"^           # Start of string
        (?:           # Either match...
         N            # N
        |             # or...
         (?:          # Match one of the following:
          A(?!.*A)    # A unless followed somewhere later by another A
         |            # or
          B(?!.*B)    # B unless...
         |            # etc. etc.
          C(?!.*C)
         |
          D(?!.*D)
         |
          E1(?!.*E1)
         |
          E2(?!.*E2)
         |
          E3(?!.*E3)
         )+           # one or more times
        )             # End of alternation
        $             # End of string", 
        RegexOptions.IgnorePatternWhitespace);
    

    This solution uses negative lookahead assertions.