re
¶
Die Python-Standard-Bibliothek re enthält ebenfalls
Funktionen für die Arbeit mit Zeichenketten. Dabei bietet re
ausgefeiltere
Möglichkeiten zur Musterextraktion und -ersetzung als der
str-Typ.
>>> import re
>>> re.sub("\n", "", welcome)
'Hello pythonistas!'
Hier wird der reguläre Ausdruck zunächst kompiliert und dann seine
re.Pattern.sub()
-Methode für den übergebenen Text aufgerufen. Ihr könnt
den Ausdruck selbst mit re.compile()
kompilieren und so ein
wiederverwendbares regex
-Objekt bilden, das auf unterschiedliche
Zeichenketten angewendet die CPU-Zyklen verringert:
>>> regex = re.compile("\n")
>>> regex.sub("", welcome)
'Hello pythonistas!'
Wenn ihr stattdessen eine Liste aller Muster erhalten möchtet, die dem
regex
-Objekt entsprechen, könnt ihr die
re.Pattern.findall()
-Methode verwenden:
>>> regex.findall(welcome)
['\n']
Bemerkung
Um das umständliche Escaping mit \
in einem regulären Ausdruck zu
vermeiden, könnt ihr rohe String-Literale wie r'C:\PATH\TO\FILE'
anstelle des entsprechenden 'C:\\PATH\\TO\\FILE'
verwenden.
re.Pattern.match()
und re.Pattern.search()
sind eng mit
re.Pattern.findall()
verwandt. Während findall
alle
Übereinstimmungen in einer Zeichenkette zurückgibt, gibt search
nur die
erste Übereinstimmung und match
nur Übereinstimmungen am Anfang der
Zeichenkette zurück. Als weniger triviales Beispiel betrachten wir einen
Textblock und einen regulären Ausdruck, der die meisten E-Mail-Adressen
identifizieren kann:
>>> addresses = """Veit <veit@cusy.io>
... Veit Schiele <veit.schiele@cusy.io>
... cusy GmbH <info@cusy.io>
... """
>>> pattern = r"[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}"
>>> regex = re.compile(pattern, flags=re.IGNORECASE)
>>> regex.findall(addresses)
['veit@cusy.io', 'veit.schiele@cusy.io', 'info@cusy.io']
>>> regex.search(addresses)
<re.Match object; span=(6, 18), match='veit@cusy.io'>
>>> print(regex.match(addresses))
None
regex.match
gibt None
zurück, da das Muster nur dann passt, wenn es am
Anfang der Zeichenkette steht.
Angenommen, ihr möchtet E-Mail-Adressen finden und gleichzeitig jede Adresse in ihre drei Komponenten aufteilen:
Personen-Name
Domänen-Name
Domänen-Suffix
Dazu setzt ihr zunächst runde Klammern ()
um die zu segmentierenden Teile
des Musters:
>>> pattern = r"([A-Z0-9._%+-]+)@([A-Z0-9.-]+)\.([A-Z]{2,4})"
>>> regex = re.compile(pattern, flags=re.IGNORECASE)
>>> match = regex.match("veit@cusy.io")
>>> match.groups()
('veit', 'cusy', 'io')
re.Match.groups()
gibt ein Tupel zurück,
das alle Untergruppen der Übereinstimmung enthält.
re.Pattern.findall()
gibt eine Liste von Tupeln zurück, wenn das Muster
Gruppen enthält:
>>> regex.findall(addresses)
[('veit', 'cusy', 'io'), ('veit.schiele', 'cusy', 'io'), ('info', 'cusy', 'io')]
Auch in re.Pattern.sub()
können Gruppen verwendet werden wobei \1
für die erste übereinstimmende Gruppe steht, \2
für die zweite usw.:
>>> regex.findall(addresses)
[('veit', 'cusy', 'io'), ('veit.schiele', 'cusy', 'io'), ('info', 'cusy', 'io')]
>>> print(regex.sub(r"Username: \1, Domain: \2, Suffix: \3", addresses))
Veit <Username: veit, Domain: cusy, Suffix: io>
Veit Schiele <Username: veit.schiele, Domain: cusy, Suffix: io>
cusy GmbH <Username: info, Domain: cusy, Suffix: io>
Die folgende Tabelle enthält einen kurzen Überblick über Methoden für reguläre Ausdrücke:
Methode |
Beschreibung |
---|---|
gibt alle sich nicht überschneidenden übereinstimmenden Muster in einer Zeichenkette als Liste zurück. |
|
wie |
|
entspricht dem Muster am Anfang der Zeichenkette und segmentiert optional die
Musterkomponenten in Gruppen; wenn das Muster übereinstimmt, wird ein
|
|
durchsucht die Zeichenkette nach Übereinstimmungen mit dem Muster; gibt in
diesem Fall ein |
|
zerlegt die Zeichenkette bei jedem Auftreten des Musters in Teile. |
|
ersetzt alle ( |
|
In Python 3.9 kann dies verwendet werden, um das Suffix oder den Dateinamen zu extrahieren. |
Checks¶
Welchen regulären Ausdruck würdet ihr verwenden, um Zeichenfolgen zu finden, die die Zahlen zwischen -3 und +3 darstellen?
Welchen regulären Ausdruck würdet ihr verwenden, um Hexadezimalwerte zu finden?