簡體   English   中英

如何將Backus-Naur Form表達式轉換為正則表達式(.Net)?

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

表達式是:

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

意思是描述符“N”或一個或多個列出的描述符而不重復。

我得到的最好的是:

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

但這並不能阻止重復。

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

這可以防止重復,但需要對元素進行特定的順序,這也不是真的好。

有任何想法嗎?

(我實際上並不確定bnf表達式本身不允許重復,但這就是我需要的。)

嗯,你可以,但它不漂亮:

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);

此解決方案使用負前瞻斷言

我不確定即使是.net正則Regex (比“常規語言”的最嚴格定義更強大)也可以做到這一點; 無論如何,除非你只要求使用正則Regex ,否則(我的想法)並沒有錯:

bool IsValid(string input)
{
    var Ns = input.Count(c => c == 'N');
    var As = input.Count(c => c == 'A');
    // etc
    var E1s = Regex.Matches(input, "E1").Count
    // etc

    var maxDescriptorCount = (new[] { As, ... ,E1s, ... }).Max();

    var isValid = 
        ((Ns == 1) && (maxDescriptorCount == 0))
        ||
        ((Ns == 0) && (maxDescriptorCount == 1))
        ;

    return isValid;
}

它是解決問題的最短代碼嗎? 不可以。它是否可讀和可維護? 我認同。

(如果你願意的話,你可以編寫一個帶有簽名int MaxN(params int[] numbers)的實用程序方法)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM