2009-03-23 13 views
1

Ich dachte, ich verstehe C# regulären Ausdrücke, aber eindeutig ist es nicht der Fall. Ich brauche Hilfe, um einen Ausdruck zu finden, der alles von START | BEGIN bis)) findet. Ausdruck kann mehrzeilig sein.Wie finde ich das mit Regular Expression?

Ex.

START(FTP_STATE, XXX(
    VAL(FTP_INITIAL_STATE, 0) 
    VAL(FTP_INBOUND,  1) 
    AL(FTP_OUTBOUND,  2) 
)) 

/**************************************************************/ 

BEGIN(FTP_TIMER_MODE, YYY(
    VAL(FTP_REMOVE_TIMER,  0) 
    VAL(FTP_NOT_REMOVE_TIMER, 1) 
)) 

/**************************************************************/ 

Jede Hilfe sehr geschätzt

+0

Ich würde empfehlen, RegexBuddy für die Arbeit mit Regular Expressions zu verwenden.Es hat mir viel Zeit gerettet;) – Alekc

Antwort

4

Try this:

(?:START|BEGIN)(?:[^)]+|\)[^)])+\)\) 

es zu erklären:

  • (?:START|BEGIN) beginnen entweder mit START oder BEGIN.
  • (?:[^)]+|\)[^)])+ Danach entweder irgendein anderes Zeichen als ein ) ([^)]+) oder ein ), die von jedem anderen Zeichen als ) folgt (\)[^)]) kann folgen. (Es gibt also keine Möglichkeit, )) mit diesem Ausdruck zu vergleichen.)
  • Schließlich die )).

Ich hoffe, dass dies Backtracking reduzieren wird.

10

Es ist gerade nach vorne; START oder BEGIN, dann irgendeine Zahl irgendeines Symbols aber nicht gierig und schließlich die zwei schließenden Klammern. . *? Nimmt eine beliebige Anzahl von Symbolen, aber so wenig wie möglich. Um über mehr als eine Zeile passen die einzelnen Zeilenoption (? S) muss aktiviert sein (Danke Alan M., dass für den Hinweis auf.)

(?s)(START|BEGIN).*?\)\) 
+0

Schöne Erklärung –

0

Ich weiß nicht, die Syntax für C#, aber in Perl es ist :

m/(BEGIN|START).*?\)\)/s 

Die macht es multiline.

Sie müssen nur sehen, wie die Regex mehrzeilige in C# machen

+0

Das passt bis zum letzten)) in der Datei, nicht die erste)) nach BEGIN oder START – Tmdean

0

Wenn Sie nicht verstehen, und wollen, lernen regexps dann mich ist regexp site

Die Lösung lassen empfehlen wahrscheinlich so etwas wie /(START|BEGIN).*))/

1

Eigentlich müssen Sie auch die VAL (...) berücksichtigen.

In Perl wäre es:

(BEGIN|START)\([^(\)\)\))].+\)\)\) 
  1. Beginnt mit BEGIN oder START
  2. Hat eine öffnende Klammer
  3. Ermöglicht nichts))) dazwischen, gierig zu vermeiden passende
  4. Endet mit drei schließenden Klammern)))
+0

Nicht wenn die Endung "))" immer auf a steht Zeile für sich. Wie auch immer, deine Regex funktioniert nicht. Es sieht so aus, als ob Sie versuchen, eine Zeichenklasse zu verwenden, als ob es ein negatives Lookahead wäre. –

+0

Guter Aufruf - auch wenn dieser Regex dem gegebenen Text entspricht - zumindest in einem schnellen php-Test mit preg_, tut die Zeichenklasse nichts. –

0
ResultString = Regex.Match(subject, @"(START|BEGIN).*?\)\)", RegexOptions.Singleline).Value; 
+0

Ich denke es sollte MultiLine sein? –

+0

Mmm wahrscheinlich hast du Recht, automatisch generierten Code von RegexBuddy, da ich mit PHP arbeiten und nicht C# (Regex ist richtig, obwohl: D) – Alekc

0

Versuchen Sie, diese

MatchCollection m = Regex.Matches(input, "(START|BEGIN).+?\\)\\)", RegexOptions.Multiline); 
1
@"(?s)(?:START|BEGIN).*?\)\)" 

Was einige der anderen "mehrzeiligen Modus" fordern tatsächlich ist einzeiligen (oder DOTALL) Modus. Das ist der Modus, bei dem der Punkt mit Zeilenumbrüchen übereinstimmt. Mehrzeiliger Modus lässt '^' den Anfang einer Zeile '$' mit dem Ende einer Zeile übereinstimmen (normalerweise entspricht die einzige Übereinstimmung dem Anfang und Ende der gesamten Zeichenfolge. Ich verwende den DOTALL-Modus mit dem Inline-Modifikator "(? S) "

+0

Danke für das Zeigen, dass Multiline/singleline Ding aus. Die Namen der Optionen sind gut gewählt; Sie können den Singleline- und Multiline-Modus gleichzeitig aktivieren ...: D –

1

Sie haben bereits Ihre Antwort, aber ich dachte, ich würde this link einwerfen, was ich sehr nützlich finde für das Erstellen/Testen von Ausdrücken. Sie können Dinge schnell testen und dann den Ausdruck in Ihren Code einfügen bin damit zufrieden