28.2 Verwendung des Moduls 

Nachdem die Syntax der regulären Ausdrücke besprochen wurde, kümmern wir uns hier um ihre konkrete Verwendung in Python. Die Beispiele der folgenden Abschnitte werden im interaktiven Modus umgesetzt und setzen voraus, dass das Modul re eingebunden wurde:
>>> import re
[»] Hinweis
Die in den folgenden Abschnitten vorgestellten Funktionen erlauben es, über den optionalen letzten Parameter flags eine Menge von Einstellungen zu übergeben, mithilfe derer sich die Auswertung der regulären Ausdrücke beeinflussen lässt. Näheres zu Flags erfahren Sie in Abschnitt 28.2.7.
28.2.1 Searching 

Die Funktion search bekommt einen regulären Ausdruck pattern und einen String string übergeben. Sie gibt daraufhin den ersten auf pattern passenden Teil-String von string als Match-Objekt[ 120 ](Näheres zu Match-Objekten erfahren Sie in Abschnitt 28.2.8. ) zurück:
>>> re.search(r"P[Yy]thon", "Python oder PYthon und Python")
<_sre.SRE_Match object; span=(0, 6), match='Python'>
Die Funktion findall hat die gleiche Schnittstelle wie search und sucht in string nach Übereinstimmungen mit dem regulären Ausdruck pattern. Alle gefundenen nicht überlappenden Übereinstimmungen werden in Form einer Liste von Strings zurückgegeben:
>>> re.findall(r"P[Yy]thon", "Python oder PYthon und Python")
['Python', 'PYthon', 'Python']
Wenn pattern eine oder mehrere Gruppen enthält, werden diese anstelle der übereinstimmenden Teil-Strings in die Ergebnisliste geschrieben.
>>> re.findall(r"P([Yy])thon", "Python oder PYthon und Python")
['y', 'Y', 'y']
>>> re.findall(r"P([Yy])th(.)n", "Python oder PYthon und Python")
[('y', 'o'), ('Y', 'o'), ('y', 'o')]
Bei mehreren Gruppen handelt es sich um eine Liste von Tupeln. Die alternative Funktion finditer funktioniert wie findall, gibt das Ergebnis aber in Form eines Iterators über Match-Objekte zurück.
28.2.2 Matching 

Die Funktion match bekommt einen regulären Ausdruck pattern und einen String string übergeben und prüft, ob pattern auf den Anfang von string passt. Bei einem erfolgreichen Matching wird das Ergebnis als Match-Objekt zurückgegeben.
>>> re.match(r"P.th", "python")
>>> re.match(r"P.th", "Python")
<_sre.SRE_Match object; span=(0, 4), match='Pyth'>
Die Funktion fullmatch hat die gleiche Schnittstelle wie match und prüft im Gegensatz zu match, ob pattern auf den kompletten String string passt.
>>> re.fullmatch(r"P.th", "Python")
>>> re.fullmatch(r"P.thon", "Python")
<_sre.SRE_Match object; span=(0, 6), match='Python'>
28.2.3 Einen String aufspalten 

Die Funktion split bekommt einen regulären Ausdruck pattern und einen String string übergeben und durchsucht string nach Übereinstimmungen mit pattern. Alle passenden Teil-Strings werden als Trennzeichen angesehen, und die dazwischenliegenden Teile werden als Liste von Strings zurückgegeben.
>>> re.split(r"\s", "Python Python Python")
['Python', 'Python', 'Python']
Eventuell vorkommende Gruppen innerhalb des regulären Ausdrucks werden ebenfalls als Elemente dieser Liste zurückgegeben:
>>> re.split(r"(,)\s", "Python, Python, Python")
['Python', ',', 'Python', ',', 'Python']
In diesem regulären Ausdruck werden alle Kommata, denen ein Whitespace folgt, als Trennzeichen behandelt.
Wenn der optionale letzte Parameter maxsplit angegeben wurde und ungleich 0 ist, wird der String maximal maxsplit-mal unterteilt. Der Rest-String wird als letztes Element der Liste zurückgegeben.
>>> re.split(r"\s", "Python Python Python", 1)
['Python', 'Python Python']
28.2.4 Teile eines Strings ersetzen 

Die Funktionen sub hat die folgende Schnittstelle:
sub(pattern, repl, string, [count, flags])
Sie sucht in string nach nicht überlappenden Übereinstimmungen mit dem regulären Ausdruck pattern. Es wird eine Kopie von string zurückgegeben, in der alle passenden Teil-Strings durch den String repl ersetzt wurden:
>>> re.sub(r"[Jj]a[Vv]a","Python", "Java oder java und jaVa")
'Python oder Python und Python'
Anstelle eines Strings kann für repl auch ein Funktionsobjekt übergeben werden. Dieses wird für jede gefundene Übereinstimmung aufgerufen und bekommt das jeweilige Match-Objekt als einzigen Parameter übergeben. Der übereinstimmende Teil-String wird durch den Rückgabewert der Funktion ersetzt.
Im folgenden Beispiel wird für den Parameter repl ein Funktionsobjekt übergeben, um unanständige Wörter in einem Text zu zensieren:
>>> def f(m):
... return "x" * len(m.group(0))
...
>>> re.sub(r"\b(\w*?sex\w*?)\b", f,
... "Wirtschaftsexperten auf Arktisexpedition")
'xxxxxxxxxxxxxxxxxxx auf xxxxxxxxxxxxxxxx'
Die Funktion sub sucht im angegebenen Text nach Wörtern, die das Teilwort »sex« enthalten. Diese Wörter werden dann mithilfe der Funktion f durch genauso viele »x« ersetzt, wie das entsprechende Wort lang ist.
Es ist möglich, durch die Schreibweisen \g<name> oder \g<index> Gruppen des regulären Ausdrucks zu referenzieren:
>>> re.sub(r"([Jj]ava)","Python statt \g<1>", "Nimm doch Java")
'Nimm doch Python statt Java'
Durch den optionalen Parameter count kann die maximale Anzahl an Ersetzungen festgelegt werden, die vorgenommen werden dürfen.
Die alternative Funktion subn funktioniert analog zu sub, gibt aber zusätzlich zum Ergebnis-String die Anzahl der vorgenommenen Ersetzungen zurück:
>>> re.subn(r"[Jj]a[Vv]a","Python", "Java oder java und jaVa")
('Python oder Python und Python', 3)
28.2.5 Problematische Zeichen ersetzen 

Die Funktion escape wandelt alle nicht-alphanumerischen Zeichen des übergebenen Strings in ihre entsprechende Escape-Sequenz um und gibt das Ergebnis als String zurück. Diese Funktion ist sinnvoll, wenn Sie einen String in einen regulären Ausdruck einbetten möchten, aber nicht sicher sein können, ob Sonderzeichen wie Punkte oder Fragezeichen enthalten sind.
>>> re.escape("Funktioniert das wirklich? ... (ja!)")
'Funktioniert\\ das\\ wirklich\\?\\ \\.\\.\\.\\ \\(ja\\!\\)'
Beachten Sie, dass die Escape-Sequenzen im String-Literal jeweils durch einen doppelten Backslash eingeleitet werden. Das liegt daran, dass das Ergebnis als String und nicht als Raw-String zurückgegeben wird.
28.2.6 Einen regulären Ausdruck kompilieren 

Die Funktion compile kompiliert einen regulären Ausdruck zu einem Regular-Expression-Objekt (RE-Objekt). Das zurückgegebene Objekt bietet im Wesentlichen den gleichen Funktionsumfang wie das Modul re, darauf ausgeführte Operationen sind aber in der Regel schneller:
>>> regexp = re.compile(r"P[Yy]thon")
>>> regexp.findall("Python oder PYthon und Python")
['Python', 'PYthon', 'Python']
Insbesondere Programme, die viele verschiedene reguläre Ausdrucke in hoher Frequenz auswerten, sollten diese kompilieren. Aufgrund eines internen Caching-Mechanismus des re-Moduls ist die häufige Auswertung desselben regulären Ausdrucks nicht kritisch.
28.2.7 Flags 

In den vorangegangenen Abschnitten wurden mehrfach die sogenannten Flags angesprochen. Das sind Einstellungen, die die Auswertung eines regulären Ausdrucks beeinflussen. Flags können Sie entweder im Ausdruck selbst durch eine Extension oder als Parameter einer der im Modul re verfügbaren Funktionen angeben. Sie beeinflussen nur den Ausdruck, der aktuell verarbeitet wird, und bleiben nicht nachhaltig im System. Jedes Flag ist als Konstante im Modul re enthalten und kann über eine Lang- oder eine Kurzversion seines Namens angesprochen werden. Tabelle 28.5 listet alle Flags auf und erläutert ihre Bedeutung.
Alias | Name | Bedeutung |
---|---|---|
re.A | re.ASCII | Wenn dieses Flag gesetzt wurde, werden die Zeichenklassen \w, \W, \b, \B, \s und \S auf den ASCII-Zeichensatz beschränkt. |
re.I | re.IGNORECASE | Wenn dieses Flag gesetzt wurde, wird die Auswertung des regulären Ausdrucks case insensitive, das heißt, dass die Zeichengruppe [A-Z] sowohl auf Groß- als auch auf Kleinbuchstaben passen würde. |
re.L | re.LOCALE | Wenn dieses Flag gesetzt wurde, werden bestimmte vordefinierte Zeichenklassen von der aktuellen Lokalisierung abhängig gemacht. Das betrifft die Gruppen \w, \W, \b, \B, \s und \S. |
re.M | re.MULTILINE |
Wenn dieses Flag gesetzt wurde, passt ^ sowohl zu Beginn des Strings als auch nach jedem Newline-Zeichen und $ vor jedem Newline-Zeichen. Normalerweise passen ^ und $ nur am Anfang bzw. am Ende des Strings. |
re.S | re.DOTALL | Wenn dieses Flag gesetzt wurde, passt das Sonderzeichen ».« tatsächlich auf jedes Zeichen. Normalerweise passt der Punkt auf jedes Zeichen außer auf das Newline-Zeichen \n. |
re.X | re.VERBOSE | Wenn dieses Flag gesetzt wurde, werden Whitespace-Zeichen wie Leerzeichen, Tabulatoren oder Newline-Zeichen im regulären Ausdruck ignoriert, solange sie nicht durch einen Backslash eingeleitet werden. Zudem leitet ein #-Zeichen einen Kommentar ein. Das heißt, dass alles hinter diesem Zeichen bis zu einem Newline-Zeichen ignoriert wird. |
Tabelle 28.5 Flags
Die meisten der zuvor vorgestellten Funktionen des Moduls re haben einen optionalen Parameter flags, über den eine Kombination von Flags angegeben werden kann:
>>> print(re.match(r"python", "Python"))
None
>>> print(re.match(r"python", "Python", re.I))
<_sre.SRE_Match object; span=(0, 6), match='Python'>
Wie Sie im Beispiel sehen, passt sich das Verhalten der Funktion match an die übergebenen Flags an. In diesem Fall wurde zuerst ein case-sensitives Matching durchgeführt und danach ein case-insensitives. Flags lassen sich mithilfe des binären ODER kombinieren, zum Beispiel:
re.I | re.S | re.M
28.2.8 Das Match-Objekt 

Die Ergebnisse von Match- oder Search-Operationen werden von den zuvor eingeführten Funktionen, beispielsweise match und search, als Match-Objekte zurückgegeben. Das Match-Objekt enthält nähere Details zu diesen gefundenen Übereinstimmungen. Dazu definiert ein Match-Objekt die folgenden Attribute:
Attribut | Beschreibung |
---|---|
pos, endpos |
Start- bzw. Endindex des Teil-Strings, auf den sich das Matching bzw. Searching bezog, das dieses Match-Objekt ergab |
re | der ursprüngliche reguläre Ausdruck als String |
string | der String, auf den sich dieses Match-Objekt bezieht |
Tabelle 28.6 Attribute eines Match-Objekts
Zugriff auf Gruppen-Matchings
Die Methode group erlaubt einen komfortablen Zugriff auf die Teil-Strings, die auf die verschiedenen Gruppen des regulären Ausdrucks gepasst haben. Wenn nur ein Argument übergeben wurde, ist der Rückgabewert ein String, ansonsten ein Tupel von Strings. Wenn eine Gruppe auf keinen Teil-String gepasst hat, wird für diese None zurückgegeben.
>>> m1 = re.match(r"(P[Yy])(th.n)", "Python")
>>> m1.group(1)
'Py'
>>> m1.group(1, 2)
('Py', 'thon')
Ein Index von 0 gibt den vollständigen passenden String zurück.
>>> m1.group(0)
'Python'
Die Methode groups gibt eine Liste aller auf die im regulären Ausdruck enthaltenen Gruppen passenden Teil-Strings zurück:
>>> m1.groups()
('Py', 'thon')
Über die Methoden start und end bzw. span kann der auf eine Gruppe passende Teil-String über seinen Start- bzw. Endindex im Eingabe-String bezogen werden:
>>> m1.start(2)
2
>>> m1.end(2)
6
>>> m1.span(2)
(2, 6)
Speziell für benannte Gruppen existiert die Funktion groupdict, die die Namen der Gruppen auf die darauf passenden Teil-Strings abbildet:
>>> m2 = re.match(r"(?P<gruppe1>P[Yy])(?P<gruppe2>th.n)", "Python")
>>> m2.groupdict()
{'gruppe1': 'Py', 'gruppe2': 'thon'}
Seit Python 3.6 erlauben Match-Objekte einen indexbasierten Zugriff, der äquivalent zu einem Aufruf von groups ist:
>>> m1[1]
'Py'
>>> m2["gruppe2"]
'thon'