2016-04-25 11 views
3

Ich dachte, dass, obwohl eine Gruppe optional war ?, dass es immer noch gierig und Zeichen verbrauchen würde, , wenn es könnte, bevor Sie zum nächsten Teil der Regex gehen.Warum ist meine optionale Gruppe nicht gierig? /(5)?.*/

Wenn ich die vereinfachte regex (5)?.* gegen (5).* (Gruppe 1 nicht optional) angeben, sehe ich eine anderes Verhalten in Python 2.7.6, auch wenn ich das gleiche Verhalten mit dem exakt gleichen Zeichenfolge erwarten:

>>> import re 
>>> s = 'before [5.5s] after' 
>>> r = re.compile(r'(5)?.*') 
>>> print r.search(s).groups() 
(None,) 

>>> r2 = re.compile(r'(5).*') 
>>> print r2.search(s).groups() 
('5',) 

Was bekomme ich nicht? Warum ist die erste Regex r nicht eine 5?

Hinweis: Ich brauche die Theorie der warum, wie jeder Versuch diese insbesondere regex Lösung wird mir nicht helfen. Dies ist ein SSCCE. Ich habe eine komplexere Regex und ich möchte wirklich die Lücke meines Wissens in Bezug auf warum die die optionale Gruppe ist nicht so gierig, wie ich gedacht hätte und möchte.

+6

Die Leute werden niemals aufhören solche Fragen zu stellen ... Weil '(5)?' Mit einer leeren Zeichenkette übereinstimmen kann, und da die Regex-Engine die Zeichenkette von links nach rechts analysiert, entspricht '(5)?' Dem Anfang von Die Zeichenfolge und '. *' stimmen mit dem Rest der Zeile überein. –

+0

Und noch, 're.compile ('(. *) (. *)'). Suche ('abc'). Groups()' ergibt '(' abc ',' ') '. Weißt du, warum? –

+0

'Suche' beginnt mit dem Vergleich vom Anfang der Zeichenfolge.Wenn es eine Übereinstimmung (wie in diesen Fällen) hat, werden andere Startindizes nicht berücksichtigt. – myaut

Antwort

4

Erstes Beispiel:

  • Ihr regulärer Ausdruck abgestimmt ist gegen die gesamte String s.
  • Daher wird das erste Zeichen von s, das eine "b" ist, gegen (5)? abgestimmt, die nicht zu einer Übereinstimmung führt. Das ist jedoch kein Problem, da (5)? ein optionaler Teil des Musters ist, so dass die Regex-Engine es nullmal anpasst und die aktuelle Position im Muster fortsetzt.
  • Der Rest der Zeichenfolge stimmt mit dem Rest des Musters überein, sodass die gesamte Zeichenfolge übereinstimmt. Die Gruppe (5) selbst hat nichts gefunden, Sie sehen also die None in Ihrem ersten Beispiel.

Zweites Beispiel:

  • Die 5 ist nicht mehr optional, so dass das erste Zeichen eines potenziell passenden String hat ein "5" sein. Daher beginnt eine mögliche Übereinstimmung bei "5" nach "vor [".
  • Um eine Übereinstimmung zu sein, muss die verbleibende Zeichenfolge mit dem verbleibenden Muster übereinstimmen .*, was es tut.

Beachten Sie, dass im Allgemeinen using the greedy .* is almost never what you want.

+0

Der Artikel ist interessant, aber der Titel ist der schlechteste aller Zeiten. –

+0

@CasimiretHippolyte Ich entschuldige mich. ;) –

+0

Ups, es ist deins, Entschuldigung. Ich meine, dass der Titel zu der Annahme führen kann, dass gierige Quantoren vermieden werden müssen * (wenn sie viel schneller sind als faule Quantoren) *. Sie sollten einen Artikel über die Möglichkeiten schreiben, faule Quantoren zu vermeiden! –