2016-12-22 2 views
1

Ich habe Mühe, meinen Fehler zu verstehen. Betrachten Sie diese Beispiele:Python Regex: Match 1 oder 2 Ziffern, am längsten zurück

A 9 Minuten Verspätung

10 Minuten

Verzögerung erfahren möchte ich 9 und 10 extrahieren sind.

So habe ich versucht, dies:

.*(\d{1,2})(?:\s)?(min|m|hour|hr|h|minutes|minute) 

test link

Aber für den letzten Fall Gruppe kehrt 0 statt 10. Ich dachte \d{1,2} war gierig und würde daher die längste Übereinstimmung zurückgeben. Andere, erfolglose Versuche:

.*(\d+)(?:\s)?(min|m|hour|hr|h|minutes|minute) 
.*([0-9]+)(?:\s)?(min|m|hour|hr|h|minutes|minute) 
+1

'\ d {1,2}' ist gierig, aber so ist '. *', Und '. *' Wird zuerst gehen. – user2357112

+0

Danke! Ich habe nicht ganz verstanden, wie es funktioniert, aber um es zu beheben, sollte ich einfach tun:. *? – Pep

+1

Ich würde das '. *' Ganz rausnehmen. Wenn Sie eine Funktion verwenden, die implizit die Übereinstimmung am Anfang der Zeichenfolge verankert, tun Sie dies nicht. Wenn Sie zum Beispiel "re.match" verwenden, sollten Sie stattdessen "re.search" verwenden. – user2357112

Antwort

1

Sie .* von der am Anfang verwendet Muster, das alle 0+ Zeichen außer Zeilenumbruchzeichen so viele wie möglich ergreift und dann mit dem Zurückverfolgen beginnt und versucht, die Teilzeichenfolgen für die nachfolgenden Untermuster aufzunehmen. Auf diese Weise verlieren Sie alle Ziffern außer der letzten in der Zahl.

Sie müssen die .* vollständig verwerfen und verwenden re.search oder re.findall mit r'(\d{1,2})\s?(?:min|m|hour|hr?|minutes?)' (siehe regex demo here):

import re 
ss = ['A 9 minutes delay experienced','a 10 minutes delay'] 
for s in ss: 
    m = re.search(r'(\d{1,2})\s?(?:min|m|hour|hr?|minutes?)', s) 
    if m: 
     print(m.group(1)) 

den See Python demo

Dieses Muster übereinstimmen, wenn er feststellt,

  • (\d{1,2}) - Gruppe 1 erfasst 1 oder 2 Ziffern (Verwenden + statt {1,2}, wenn Sie mehr Zahlen erwarten)
  • \s?-1 oder 0 Whitespaces (vielleicht * ist noch zuverlässiger)
  • (?:min|m|hour|hr?|minutes?) - min, m, hour, h, hr usw., ein nicht Erfassungsgruppe, die nur zum Gruppieren verwendet wird.
+1

Danke für die detaillierte Antwort und Arbeitscode! – Pep

1

Hmm .* gierig ist allready, aber wollen Sie zwei Zahlen extrahieren - halten Sie es einfach, so etwas wie .*?(\d+).*(\d+) wird die Arbeit machen