2016-08-02 54 views
1

passend ich diese Codezeilen für Take Operatoren in Klammern haben:C# regex für sepcific Text in verschachtelten Klammern

string filtered = Regex.Replace(input, "\\(.*?\\)", string.Empty); 
var result = filtered.Split(new[] { ' ' }, 
      StringSplitOptions.RemoveEmptyEntries) 
      .Where(element => element == "OR" || element == "AND");  
string temp = string.Join(" ", result); 

Diese Linien funktionieren nicht für verschachtelte Klammern.

Zum Beispiel; es arbeitet für diesen Eingang:

X1 OR (X2 AND X3 AND X4 AND X5) OR X6 

Es gib mir dieses Ergebnis: OR OR

Aber, wenn meine Eingabe mehr als eine verschachtelte Klammern hat, funktioniert es falsch.

Für diesen Eingang:

X1 OR (X2 AND(X3 AND X4) AND X5) OR X6 

ich für Ergebnis nehmen wollen OR OR aber er druckt ODER UND ODER.

Obwohl es zwei ( Zeichen in Zeichenfolge gibt, wenn es die Verarbeitung nach dem ersten Zeichen ) endet.

Wie kann ich mein Regex-Muster anpassen?

+1

Sie keine regulären Ausdrücke für Hierarchien verwenden sollten (Code; XML et al) – MickyD

+0

Siehe auch https://stackoverflow.com/questions/19596502/regex-nested-parentheses. –

+0

Der zum Schließen dieser Frage verwendete ist kein vollständiges Duplikat, obwohl er das Konzept erklärt und eine fast exakte Lösung bietet. –

Antwort

2

Ihre \(.*?\) regex enthält 3 Teile: 1) \( Literal ( passenden, 2) .*?lazy Punktanpassungsmuster (das entspricht 0+ irgendwelche anderen Zeichen als eine Neuen-Zeile, so wenig wie möglich, bis zum ersten ), und 3) ein \), das einem Literal ) entspricht.

Verwenden balancing constructwenn die Saiten Sequenzen haben, können nicht entkommen:

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

Der Punkt hier ist, dass der Ausdruck nicht mit Ankern (wie in What are regular expression Balancing Groups) eingeschlossen werden sollte.

Einzelheiten:

  • \( - eine wörtliche (
  • (?> - Beginn einer Atomgruppe, in sie zu verhindern Rückzieher
    • [^()] - alle Zeichen außer ( und )
    • | - oder
    • (?<o>)\( - passt eine wörtliche ( und schiebt einen leeren Wert in den Stack "o"
    • | - oder
    • (?<-o>)\) - entspricht einem wörtlichen ) und entfernt einen Wert von Stapel "o"
  • )* - null oder mehr Vorkommen der Atomgruppe sind
  • abgestimmt
  • \) - ein Literal )
  • (?(o)(?!)) - ein konditionelles Konstrukt, das die Übereinstimmung nicht besteht, wenn Stapel "o" Werte enthält (ist nicht leer).

Siehe regex demo.

var input = "X1 OR (X2 AND(X3 AND X4) AND X5) OR X6"; 
var filtered = Regex.Replace(input, @"\((?>[^()]|(?<o>)\(|(?<-o>)\))*\)(?(o)(?!))", string.Empty); 
var result = filtered.Split(new[] { ' ' }, 
    StringSplitOptions.RemoveEmptyEntries) 
    .Where(element => element == "OR" || element == "AND");  
var temp = string.Join(" ", result); 

Siehe C# demo

+0

Es löst mein Problem. Danke für Ihr Interesse. –

+0

Wenn Sie die Frage lieber löschen möchten, lassen Sie es mich wissen, ich lösche meine Antwort. –

+0

Ich möchte für diese Frage bleiben. Weil ich Anfänger für C# bin und ich konnte dieses Problem nicht lösen, obwohl ich in diesem Thema forsche. Ihre Antwort kann anderen Menschen wie mir helfen. Nochmals vielen Dank .. –