2013-02-22 13 views
6

corrispondenza Se ho una stringa come questa ...C# convalidare quella stringa contiene il numero di staffe

"123[1-5]553[4-52]63244[19-44]" 

... qual è il modo migliore per convalidare le seguenti condizioni:

  1. Ogni aperto staffa ha una corrispondenza stretta staffa
  2. ci sono più di 3 set di staffe
  3. non ci sono no parentesi annidate (vale a dire, [123- [4] 9])

Sarebbe una regex essere in grado di validare tutti questi scenari? In caso contrario, che ne dici di LINQ?

+0

Penso che l'espressione regolare funzionerebbe e restituirò tutte le corrispondenze racchiuse da '[...]'. Se fossi meglio con regex ti darei qualcosa su cui lavorare. ;) – IAbstract

+0

@mbeckish la domanda collegata ha indirizzo # 1 sopra ma non # 2 o # 3 quindi non penso che sia un duplicato esatto. Voglio disabilitare le parentesi annidate mentre la domanda collegata le include in modo specifico. – user685869

risposta

9

Perché non si consente la nidificazione, è possibile utilizzare un'espressione regolare:

^([^[\]]*\[[^[\]]*\]){0,3}[^[\]]*$ 

Spiegazione:

  • (...){0,3} partite fino a tre serie di quanto segue:
    • [^[\]]* partite opzionali caratteri non parentesi
    • \[ corrisponde a [ per aprire un gruppo
    • [^[\]]* partite opzionali caratteri non staffa all'interno del gruppo
    • \] partite ] per chiudere il gruppo
  • Infine, caratteri non staffa [^[\]]* partite facoltativi dopo che tutti i gruppi
+0

Non sembra essere valido quando eseguo il test con regexhero (tester .NET). Il primo numero nella ripetizione è necessario. – nhahtdh

+0

@nhahtdh: non lo sapevo; grazie – SLaks

+0

@SLaks ti ringrazio molto per la regex, ma ancora più importante, per una grande spiegazione. – user685869

5

Il modo più veloce per fare questo sarebbe solo per scorrere la stringa

bool Validate(string input) 
{ 
    int braceBalance = 0; 
    int openCount = 0; 
    for (int i = 0; i < input.Length; i++) 
    { 
     if (input[i] == '[') 
     { 
      braceBalance++; 
      openCount++; 
     } 
     if (openCount > 3) return false; // More than 3 pairs 
     if (input[i] == ']') braceBalance--; 
     // Check for nesting: 
     if (braceBalance < -1 || braceBalance > 1) return false; 
    } 
    return (braceBalance == 0); // Check for equal number of opening and closing 
} 

RegEx e Linq saranno entrambi hanno una maggiore sovraccarico di questo (anche se a seconda dell'applicazione in uso, che potrebbe non importa).

+0

grazie per l'ottima risposta! Non ho bisogno di convalidare questo tipo di dati molto spesso e le stringhe sono relativamente corte, quindi il sovraccarico aggiunto della regex è accettabile per i miei scopi. – user685869

+0

Questo è spesso il caso, e RegEx è abbastanza utile in quella situazione. –

1

solo per vedere se sarebbe plausibile, ecco un LINQ: soluzione y:

bool[] b = 
    input.Where(c => c == '[' || c == ']') 
    .Select((c,i) => (c == '[') == (i % 2 == 0)) 
    .ToArray(); 

bool valid = b.Length % 2 == 0 && b.Length <= 6 && b.All(i => i); 

Filtra i caratteri [ e ], quindi controlla che vi siano solo parentesi alternate (a partire da [), un numero pari e non più di 6 di esse.

Problemi correlati