2016-05-22 8 views
0

Ich habe ein Problem mit meiner Bedingung auf meiner Vorlage Klasse. Was mache ich falsch?Regex conditition

/@if\((?P<condition>.*)\)\n*\s*(?P<content>(?s:[\=\"\;\,\$\{\}\_\(\)\.\!\'\-\:\s\/\<\>\w\näöüÄÖÜèéà@]*))@endif/m 

REGEX-Link: https://regex101.com/r/hE4hX3/3

+0

Wie ich sehe, ist es als "0" == '0''angepasst. Was ist los mit dir? –

+0

das ist ein Beispiel :-) Es geht um die 2 Bedingungen. Es braucht sie nur als eins. Aber ich möchte als zwei akzeptieren – Neonlight

Antwort

1

Verwenden Sie anstelle der Liste der zulässigen Zeichen die Liste der verbotenen Zeichen mit negierten Zeichenklassen. Beispiel:

~ 
@if \((?P<condition> [^)]*) \) 
\s* 
(?P<content> [^@]*+ (?: @(?!endif\b) [^@]*)*+) 
@endif 
~x 

demo

Anstelle von .* für den Zustand (das nicht weiß, wo zu stoppen), [^)]* verwenden, die alle bis zur schließenden Klammer greift.

Gleiches für den Inhalt, verwenden Sie [^@]* und überprüfen Sie nach jedem , wenn "endif" folgt. (auf diese Weise "@" wird in den Inhalt erlaubt.)

Sonstiges: \n*\s* Schreiben macht keinen Sinn, weil die beiden sind optional und \s enthält bereits \n, deshalb habe ich es entfernt.

+0

Danke auch. Jetzt habe ich zwei Lösungen. Die nächste Herausforderung ist es, das andere in meinem Zustand zu implementieren :-D – Neonlight

+0

ist nicht alles das tanzt über '@ endif' bedeutet genau' ([\ s \ S] *?) @ Endif'? –

+0

@vp_arth: Nicht wirklich, es ist etwas schneller, es so zu schreiben, weil Sie die Verwendung eines nicht-gierigen Quantifier (das von Natur aus langsam ist) vermeiden und die Anzahl der Schritte reduzieren. Beachten Sie außerdem, dass alle Quantifier Possessiv sind, um das Zurückverfolgen zu verbieten.Dies ist besonders nützlich bei großem Text, wenn die Backtracking-Grenze erreicht werden kann. Beachten Sie, dass bei Verwendung eines nicht gierigen Quantifizierers für jedes Zeichen das folgende Untermuster getestet wird und nicht das nächste Zeichen usw. annehmen kann. Der gierige Quantifizierer muss diesen Job nicht machen. –

0

sollten Sie ungreedy Operator *? und g Flag auf mehrere Übereinstimmungen verwenden, um zu erreichen, was Sie wollen:

/@if\((?P<condition>.*)\)\n*\s*(?P<content>(?s:[\=\"\;\,\$\{\}\_\(\)\.\!\'\-\:\s\/\<\>\w\näöüÄÖÜèéà@]*?))@endif/mg

Oder vereinfacht:

/@if\((?P<condition>.*?)\)\s*(?P<content>([\s\S]*?))@endif/mg

Regex101


Regexps ist schlecht Werkzeug, um Dinge wie diese zu machen.
Zum Beispiel können Sie verschachtelte if s jetzt nicht verwenden.
Viel besser ist es, einen einfachen Parser zu implementieren, der seine Arbeit korrekt macht und auf neue Syntax erweitert werden kann.

+0

Vielen Dank für Ihre Hilfe. Es funktioniert wunderbar :-D. Ich lerne etwas auf – Neonlight

+0

Hmm, Ihre Antwort sind ein bisschen anders als die anderen. Aber beide funktioniert gut. Jetzt werde ich beide analysieren um zu lernen. – Neonlight

+0

Lesen Sie unter Zeile Abschnitt meiner Antwort. Regexps sind ein falsches Werkzeug dafür. –