Python Regex - So erhalten Sie Positionen und Werte von Übereinstimmungen


110

Wie kann ich mit dem reModul die Start- und Endpositionen aller Spiele ermitteln ? Zum Beispiel möchte ich angesichts des Musters r'[a-z]'und der Zeichenfolge 'a1b2c3d4'die Positionen erhalten, an denen jeder Buchstabe gefunden wird. Im Idealfall möchte ich auch den Text des Spiels zurückbekommen.


Sehen Sie, ob dies hilft, Objekte
abzugleichen

Antworten:


139
import re
p = re.compile("[a-z]")
for m in p.finditer('a1b2c3d4'):
    print(m.start(), m.group())

3
Dies liefert keinen Index für andere Gruppen in einer Übereinstimmung. Regex = r '([az]) (0-9)' m.start gilt für Gruppe (), nicht für Gruppe (1)
StevenWernerCS

@StevenWernerCS start()akzeptiert möglicherweise eine Gruppennummer. Wenn Sie also einen Index der n-ten Gruppe wünschen, verwenden Siestart(n)
Hi-Angel

@ hi-angel yep, siehe meine Antwort vom letzten Jahr, die genau das tut
StevenWernerCS

51

Genommen von

Regulärer Ausdruck HOWTO

span () gibt sowohl Start- als auch Endindizes in einem einzigen Tupel zurück. Da die Übereinstimmungsmethode nur prüft, ob die RE am Anfang eines Strings übereinstimmt, ist start () immer Null. Die Suchmethode von RegexObject-Instanzen durchsucht jedoch die Zeichenfolge, sodass die Übereinstimmung in diesem Fall möglicherweise nicht bei Null beginnt.

>>> p = re.compile('[a-z]+')
>>> print p.match('::: message')
None
>>> m = p.search('::: message') ; print m
<re.MatchObject instance at 80c9650>
>>> m.group()
'message'
>>> m.span()
(4, 11)

Kombinieren Sie das mit:

In Python 2.2 ist auch die finditer () -Methode verfügbar, die eine Folge von MatchObject-Instanzen als Iterator zurückgibt.

>>> p = re.compile( ... )
>>> iterator = p.finditer('12 drummers drumming, 11 ... 10 ...')
>>> iterator
<callable-iterator object at 0x401833ac>
>>> for match in iterator:
...     print match.span()
...
(0, 2)
(22, 24)
(29, 31)

Sie sollten in der Lage sein, etwas in der Größenordnung von zu tun

for match in re.finditer(r'[a-z]', 'a1b2c3d4'):
   print match.span()

Sie können es verwenden wie re.search(r'abbit', "has abbit of carrot").span(0)-(4, 9)
Константин Ван

Der 'Endindex', der von zurückgegeben wird, span()ist wie der 'Stopp' in Pythons Slice-Notation, da er bis zu diesem Index reicht, diesen jedoch nicht enthält. siehe hier .
Wayne

20

Für Python 3.x.

from re import finditer
for match in finditer("pattern", "string"):
    print(match.span(), match.group())

Sie erhalten \nfür jeden Treffer in der Zeichenfolge getrennte Tupel (bestehend aus dem ersten und dem letzten Index des Spiels) und das Spiel selbst.


2

Beachten Sie, dass der Bereich und die Gruppe für mehrere Erfassungsgruppen in einem regulären Ausdruck indiziert sind

regex_with_3_groups=r"([a-z])([0-9]+)([A-Z])"
for match in re.finditer(regex_with_3_groups, string):
    for idx in range(0, 4):
        print(match.span(idx), match.group(idx))

1
Danke, das hat sich als super nützlich erwiesen und scheint ziemlich begraben zu sein. Falls jemand dies benötigt: Wenn Sie benannte Erfassungsgruppen verwenden, können Sie den Index einer Gruppe mit <match> .re.groupindex ermitteln und von dort aus die entsprechende Spanne mit dem von Ihnen beschriebenen Ansatz ermitteln
madimov

Woher kommt das 4?
Funkgesteuert

@RadioControlled number_of_known_groups_in_the_regex + 1, da der Bereich [Start, Ende] ohne Ende ist
StevenWernerCS

@StevenWernerCS so dass es zu Fällen nicht verallgemeinert nicht , wo Anzahl der Gruppen ist nicht bekannt ...
Radio Controlled
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.