2016-07-12 6 views
0

Ziel: finden Sie ein zweites Muster und betrachten es als eine Übereinstimmung nur, wenn es das erste Mal ist, das Muster nach einem anderen Muster beobachtet wurde.Finden Sie das erste ReGex-Muster nach einem anderen Muster

Hintergrund:

Ich verwende Python-2.7 Regex

Ich habe eine bestimmte Regex Match, das ich Probleme mit. Ich versuche, den Text zwischen den eckigen Klammern im folgenden Beispiel zu erhalten.

Sample comments: 

    [98 g/m2 Ctrl (No IP) 95 min 340oC   ] 

    [ ] 

brauche ich die Zeile:

98 g/m2 Ctrl (No IP) 95 min 340oC 

Das Problem ist die unbestimmte Anzahl von weißen Leerzeichen, Tabulatoren und neuer Linien zwischen dem Suchmuster Sample comments: und dem Spiel möchte ich gebe mir Mühe .

Bester Versuch:

Ich bin in der Lage, den ersten Teil, leicht

match = re.findall(r'Sample comments:[.+\n+]+', string) 

Aber ich kann nicht das Spiel will die Länge ich paßt den Abschnitt zwischen dem Platz greifen Klammern,

match = re.findall(r'Sample comments:[.+\n+]+\[(.+)\]', string) 

Mein Denken:

Gibt es eine Möglichkeit, ReGex zu verwenden, um die erste Instanz des Musters \[(.+)\] nach einer Übereinstimmung des Musters Sample comments: zu finden? Oder gibt es eine robustere Möglichkeit, das Bit zwischen den quadratischen Klammern in meinem Beispielfall zu finden.

Danke,

Michael

+0

Nicht ganz klar. Vielleicht genügen [Beispielkommentare: \ s * \ [(. *?) \ S *] '] (https://regex101.com/r/rH4kS1/1)? Siehe http://ideone.com/FZ5Ee0 –

+0

Dein funktioniert, aber ich verstehe nicht wie. Enthält '\ s' Leerzeichen und' \ n'? Es gibt definitiv eine neue Zeile in meinem Sample, aber es scheint trotzdem zu funktionieren. –

+0

Ja, '\ s' entspricht allen Leerzeichen, vertikal und horizontal. –

Antwort

3

Ich schlage vor,

r'Sample comments:\s*\[(.*?)\s*]' 

Siehe regex und IDEONE demo

Der Punkt ist, die \s* Streichhölzer null oder mehr Leerzeichen, beide vertikal (Zeilenumbrüche) und horizontal verwendet wird. Siehe Python re reference:

\s
Wenn der UNICODE Flag nicht angegeben, sie paßt zu jedem Leerzeichen, diese [ \t\n\r\f\v] den Satz entsprechen. Das Flag LOCALE hat keinen zusätzlichen Effekt auf die Übereinstimmung des Speicherplatzes.Wenn UNICODE festgelegt ist, entspricht dies den Zeichen [ \t\n\r\f\v] und allem, was in der Unicode-Eigenschaftendatenbank als Leerzeichen klassifiziert ist.

Musterdetails:

  • Sample comments: - eine Folge von literal Zeichen
  • \s*-0 oder mehr Leerzeichen
  • \[ - ein Literal [
  • (.*?) - Gruppe 1 (zurück von re.findall) Capturing 0+ alle Zeichen aber ein Newline als f ew wie möglich bis zum ersten ...
  • \s* - 0+ Whitespaces und
  • ] - eine wörtliche ] (man beachte es nicht außerhalb der Zeichenklasse entgangen sein muss).
+0

Als ich ReGex gelernt habe, wurde mir zweideutig gesagt, dass '\ s' mit Leerzeichen übereinstimmt. Ich nahm irrtümlicherweise an, dass dies ein Leerzeichen bedeutet. Als Ergebnis dachte ich nicht einmal, dass dieser Teil des Codes mein Problem war. Vielen Dank! –

+0

Ein Leerzeichen kann mit einem bloßen '[]' oder einem Leerzeichen verglichen werden. Wenn Sie den horizontalen Whitespace in Python abgleichen wollen, können Sie einfach '[\ t]' oder '[^ \ S \ r \ n]' verwenden (diese Patterns sind in den meisten Situationen geeignet). –

0

nicht sicher, ob ich das Problem richtig verstanden habe, aber re.findall('Sample comments:[^\\[]*\\[([^\\]]*)\\]', string) scheint zu funktionieren.

Oder vielleicht re.findall('Sample comments:[^\\[]*\\[[ \t]*([^\\]]*?)[ \t]*\\]', string), wenn Sie die letzten Leerzeichen von Ihrer Linie entfernen möchten?