2017-03-22 4 views
1

Ich habe eine Zeichenfolge, die ich in bestimmten Segmenten aufgeteilt werden möchte, aber ich kann nicht das richtige Segment der Zeichenfolge aufgrund von zwei Vorkommen des gleichen Musters übereinstimmen.Finden Sie bestimmte Segmente mit Regex

Mein string:

@if(text.text isempty){<customer_comment>@cc{txt_without_comments}[email protected]</customer_comment>}else{@if(text.answer=='no'){<customer_comment>@{text.text}</customer_comment>}else{<answer>@{text.text}</answer>}[email protected]}[email protected] 

I entsprechen müssen: @if (text.text isempty) {@ cc {txt_without_comments} cc @} else {....} endif @

und nicht die verschachtelten Punkte im else-Block.

Hier ist meine unvollständige regex:

(?<match>(?<open>@if\((?<statement>[^)]*)\)\s*{)(?<ifblock>(.+?)(?:}else{)(?<elseblock>.*))(?<-open>)}[email protected]) 

Diese Regex ist zu gierig in der ifblock Gruppe es soll bei der ersten stoppen} else {Muster.

Edit: Dies ist das genaue Ergebnis i produzieren wollen:

match: @if(text.text isempty){<customer_comment>@cc{txt_without_comments}[email protected]</customer_comment>}else{@if(text.answer=='no'){<customer_comment>@{text.text}</customer_comment>}else{<answer>@{text.text}</answer>}[email protected]}[email protected] 

statement: text.text isempty 

ifblock: <customer_comment>@cc{txt_without_comments}[email protected]</customer_comment> 

elseblock: @if(text.answer=='no'){<customer_comment>@{text.text}</customer_comment>}else{<answer>@{text.text}</answer>}[email protected] 
+0

Bitte geben Sie das genaue erwartete Ergebnis an. –

+1

Mein gewünschtes Ergebnis wird auf die Frage gepostet. –

Antwort

1

Sie sind nicht balancing groups funktioniert nicht richtig. Balancing-Gruppen müssen verwendet werden, um einige Werte mit einem Capture in den Stack zu schieben und mit anderen Captures aus dem Stack zu entfernen. Dann ist conditional construct erforderlich, um zu überprüfen, ob der Gruppenstapel leer ist. Ist dies nicht der Fall, wird das Match nicht erzwungen Rückverfolgung.

Also, wenn die Regex die einzige Möglichkeit für Sie, ist diese Strings entsprechen, verwenden Sie die folgenden Schritte aus:

(?s)(?<match>@if\((?<statement>[^)]*)\)\s*{\s*(?<ifblock>.*?)\s*}\s*else\s*{\s*(?<elseblock>@if\s*\((?:([email protected]\s*\(|\}\s*[email protected]).|(?<a>)@if\s*\(|(?<-a>)\}\s*[email protected])*(?(a)(?!)))\}\s*[email protected]) 

die regex demo See. Das Schreiben eines benutzerdefinierten Parsers könnte hier jedoch ein besserer Ansatz sein.

Muster Details:

  • (?s) - Einzeilenmode auf (. Spiele Newline)
  • (?<match> - Beginn der äußeren Gruppe "match"
  • @if\( - eine wörtliche char Sequenz @if(
  • (?<statement>[^)]*) - Gruppe "Anweisung" erfassen 0+ Zeichen anders als )
  • \)\s*{\s* - ), 0+ Whitespaces, {, 0+ Whitespaces
  • (?<ifblock>.*?) - Gruppe "ifblock", die alle 0+ Zeichen, so wenig wie möglich bis zum ersten einfängt ...
  • \s*}\s*else\s*{\s* - 0+ Whitespaces, }, 0+ Whitespaces, else, 0+ Whitespaces, {, 0+ Whitespaces
  • (?<elseblock>@if\s*\((?:([email protected]\s*\(|\}\s*[email protected]).|(?<a>)@if\s*\(|(?<-a>)\}\s*[email protected])*(?(a)(?!))) - Gruppe "elseblock" Erfassung:
    • @if\s*\( - @if, 0+ Whitespaces, (
    • (?: - Beginn der Wechsel-Gruppe, dass wiederholt 0+ mal
    • )* - Ende der Altergruppe
    • 012.360.- bedingtes Prüfen, ob die ausgewogene Menge an if und endif
  • \}\s*[email protected] abgestimmt ist - }, 0+ Leerzeichen, [email protected]
  • ) - Ende der äußeren "match" -Gruppe.