re — Operationen mit regulären Ausdrücken¶
Quellcode: Lib/re/
Dieses Modul bietet Operationen mit regulären Ausdrücken, ähnlich denen in Perl.
Sowohl Muster als auch die zu durchsuchenden Zeichenketten können Unicode-Zeichenketten (str) oder 8-Bit-Zeichenketten (bytes) sein. Unicode- und 8-Bit-Zeichenketten lassen sich allerdings nicht mischen: Du kannst eine Unicode-Zeichenkette nicht mit einem bytes-Muster abgleichen und umgekehrt. Ebenso muss bei einer Ersetzung die Ersatzzeichenkette denselben Typ haben wie Muster und Suchzeichenkette.
Reguläre Ausdrücke verwenden den Backslash ('\'), um besondere Formen anzuzeigen oder um besondere Zeichen ohne ihre besondere Bedeutung verwenden zu können. Das kollidiert damit, dass Python dasselbe Zeichen zu demselben Zweck in Zeichenkettenliteralen verwendet: Um zum Beispiel auf einen wörtlichen Backslash zu passen, muss man unter Umständen '\\\\' als Musterzeichenkette schreiben, denn der reguläre Ausdruck muss \\ sein und jeder Backslash muss in einem gewöhnlichen Python-Zeichenkettenliteral als \\ ausgedrückt werden. Beachte außerdem, dass ungültige Escape-Sequenzen bei Pythons Verwendung des Backslashs in Zeichenkettenliteralen jetzt eine SyntaxWarning erzeugen und künftig einen SyntaxError. Das gilt auch dann, wenn es sich um eine gültige Escape-Sequenz für einen regulären Ausdruck handelt.
Die Lösung besteht darin, für Muster regulärer Ausdrücke Pythons Raw-String-Schreibweise zu verwenden. In einem Zeichenkettenliteral mit dem Präfix 'r' werden Backslashes nicht besonders behandelt. r"\n" ist also eine Zeichenkette aus zwei Zeichen, nämlich '\' und 'n', während "\n" eine Zeichenkette aus einem Zeichen ist, nämlich einem Zeilenumbruch. Üblicherweise werden Muster in Python-Code in dieser Raw-String-Schreibweise ausgedrückt.
Wichtig: Die meisten Operationen mit regulären Ausdrücken stehen sowohl als Funktionen auf Modulebene als auch als Methoden an kompilierten regulären Ausdrücken zur Verfügung. Die Funktionen sind Abkürzungen, bei denen du kein Regex-Objekt vorab kompilieren musst, denen aber einige Parameter zur Feinabstimmung fehlen.
Siehe auch
Das Modul regex von Dritten hat eine API, die zu der des Standardbibliotheksmoduls re passt, bietet aber zusätzliche Funktionalität und eine umfassendere Unicode-Unterstützung.
Syntax regulärer Ausdrücke¶
Ein regulärer Ausdruck (oder RE) gibt eine Menge von Zeichenketten an, die auf ihn passen. Mit den Funktionen dieses Moduls kannst du prüfen, ob eine bestimmte Zeichenkette auf einen gegebenen regulären Ausdruck passt (oder ob ein gegebener regulärer Ausdruck auf eine bestimmte Zeichenkette passt, was auf dasselbe hinausläuft).
Reguläre Ausdrücke lassen sich zu neuen regulären Ausdrücken verketten: Sind A und B beide reguläre Ausdrücke, so ist auch AB ein regulärer Ausdruck. Passt eine Zeichenkette p auf A und eine weitere Zeichenkette q auf B, so passt die Zeichenkette pq im Allgemeinen auf AB. Das gilt, solange A oder B keine Operationen mit niedriger Priorität enthalten, keine Randbedingungen zwischen A und B bestehen und keine Verweise auf numerierte Gruppen vorkommen. So lassen sich komplexe Ausdrücke leicht aus einfacheren Grundausdrücken wie den hier beschriebenen zusammensetzen. Einzelheiten zur Theorie und zur Umsetzung regulärer Ausdrücke findest du im Buch von Friedl [Frie09] oder in fast jedem Lehrbuch über Compilerbau.
Es folgt eine kurze Erläuterung des Aufbaus regulärer Ausdrücke. Weitere Informationen und eine sanftere Darstellung findest du unter HOWTO zu regulären Ausdrücken.
Reguläre Ausdrücke können besondere und gewöhnliche Zeichen enthalten. Die meisten gewöhnlichen Zeichen wie 'A', 'a' oder '0' sind die einfachsten regulären Ausdrücke: Sie passen einfach auf sich selbst. Gewöhnliche Zeichen lassen sich verketten, last passt also auf die Zeichenkette 'last'. (Im weiteren Verlauf dieses Abschnitts schreiben wir REs in this special style, also meist ohne Anführungszeichen, und Zeichenketten, auf die der RE passen soll, als 'in single quotes'.)
Manche Zeichen wie '|' oder '(' sind besonders. Besondere Zeichen stehen entweder für Klassen gewöhnlicher Zeichen oder beeinflussen, wie die regulären Ausdrücke um sie herum gedeutet werden.
Wiederholungsoperatoren oder Quantoren (*, +, ?, {m,n} und so weiter) lassen sich nicht unmittelbar verschachteln. Das verhindert Mehrdeutigkeit mit dem nachgestellten Modifikator ? für nicht gierige Wiederholung und mit anderen Modifikatoren in anderen Umsetzungen. Um auf eine innere Wiederholung eine zweite anzuwenden, lassen sich Klammern verwenden. Der Ausdruck (?:a{6})* passt zum Beispiel auf jedes Vielfache von sechs 'a'-Zeichen.
Besondere Zeichen¶
Die besonderen Zeichen sind:
.¶
(Punkt.) Im voreingestellten Modus passt er auf jedes Zeichen außer einem Zeilenumbruch. Ist das Flag DOTALL angegeben, passt er auf jedes Zeichen einschließlich eines Zeilenumbruchs. (?s:.) passt unabhängig von den Flags auf jedes Zeichen.
^¶
(Caret.) Passt auf den Anfang der Zeichenkette und im MULTILINE-Modus auch unmittelbar nach jedem Zeilenumbruch.
$¶
Passt auf das Ende der Zeichenkette oder unmittelbar vor den Zeilenumbruch am Ende der Zeichenkette und im MULTILINE-Modus auch vor einem Zeilenumbruch. foo passt sowohl auf ‚foo‘ als auch auf ‚foobar‘, während der reguläre Ausdruck foo$ nur auf ‚foo‘ passt. Interessanter: Die Suche nach foo.$ in 'foo1\nfoo2\n' findet normalerweise ‚foo2‘, im MULTILINE-Modus aber ‚foo1‘. Die Suche nach einem einzelnen $ in 'foo\n' findet zwei (leere) Fundstellen: eine unmittelbar vor dem Zeilenumbruch und eine am Ende der Zeichenkette.
*¶
Der entstehende RE passt auf 0 oder mehr Wiederholungen des vorangehenden RE, und zwar auf so viele wie möglich. ab* passt auf ‚a‘, auf ‚ab‘ oder auf ‚a‘ gefolgt von beliebig vielen ‚b‘.
+¶
Der entstehende RE passt auf 1 oder mehr Wiederholungen des vorangehenden RE. ab+ passt auf ‚a‘ gefolgt von beliebig vielen, aber mindestens einem ‚b‘. Auf ein einzelnes ‚a‘ passt er nicht.
?¶
Der entstehende RE passt auf 0 oder 1 Wiederholungen des vorangehenden RE. ab? passt auf ‚a‘ oder auf ‚ab‘.
*?, +?, ??¶
Die Quantoren '*', '+' und '?' sind alle gierig: Sie passen auf so viel Text wie möglich. Manchmal ist dieses Verhalten nicht gewünscht. Wird der RE <.*> auf '<a> b <c>' angewendet, passt er auf die gesamte Zeichenkette und nicht nur auf '<a>'. Ein ? nach dem Quantor macht ihn nicht gierig beziehungsweise minimal: Dann deckt er so wenige Zeichen wie möglich ab. Der RE <.*?> passt nur auf '<a>'.
*+, ++, ?+¶
Wie die Quantoren '*', '+' und '?' passen auch jene mit angehängtem '+' auf so viele Wiederholungen wie möglich. Anders als die echt gierigen Quantoren erlauben sie aber kein Zurückgehen, wenn der folgende Ausdruck scheitert. Sie heißen besitzergreifende Quantoren. a*a passt zum Beispiel auf 'aaaa': a* deckt zunächst alle 4 'a' ab, beim letzten 'a' geht der Ausdruck dann zurück, sodass a* am Ende insgesamt 3 'a' abdeckt und das vierte 'a' vom abschließenden 'a' erfasst wird. Wird dagegen a*+a auf 'aaaa' angewendet, deckt a*+ alle 4 'a' ab. Findet das abschließende 'a' dann keine weiteren Zeichen, kann der Ausdruck nicht zurückgehen und scheitert. x*+, x++ und x?+ entsprechen (?>x*), (?>x+) beziehungsweise (?>x?).
Added in version 3.11.
{m}¶
Gibt an, dass genau m Kopien des vorangehenden RE passen sollen. Bei weniger Wiederholungen passt der gesamte RE nicht. a{6} passt zum Beispiel auf genau sechs 'a'-Zeichen, nicht aber auf fünf.
{m,n}¶
Der entstehende RE passt auf m bis n Wiederholungen des vorangehenden RE, und zwar auf so viele wie möglich. a{3,5} passt zum Beispiel auf 3 bis 5 'a'-Zeichen. Lässt man m weg, ist die Untergrenze null. Lässt man n weg, ist die Obergrenze unendlich. So passt a{4,}b auf 'aaaab' oder auf tausend 'a'-Zeichen gefolgt von einem 'b', nicht aber auf 'aaab'. Das Komma darf nicht weggelassen werden, sonst würde der Modifikator mit der vorher beschriebenen Form verwechselt.
{m,n}?¶
Der entstehende RE passt auf m bis n Wiederholungen des vorangehenden RE, und zwar auf so wenige wie möglich. Das ist die nicht gierige Fassung des vorigen Quantors. Bei der Zeichenkette 'aaaaaa' aus sechs Zeichen passt a{3,5} zum Beispiel auf 5 'a'-Zeichen, während a{3,5}? nur auf 3 Zeichen passt.
{m,n}+¶
Der entstehende RE passt auf m bis n Wiederholungen des vorangehenden RE, und zwar auf so viele wie möglich, ohne Punkte zum Zurückgehen anzulegen. Das ist die besitzergreifende Fassung des obigen Quantors. Bei der Zeichenkette 'aaaaaa' aus sechs Zeichen versucht a{3,5}+aa zum Beispiel, 5 'a'-Zeichen abzudecken. Da es dann noch 2 weitere 'a' braucht, bräuchte es mehr Zeichen als vorhanden und scheitert daher. a{3,5}aa passt dagegen: a{3,5} erfasst erst 5, nach dem Zurückgehen 4 'a', und die beiden letzten 'a' werden vom abschließenden aa im Muster erfasst. x{m,n}+ entspricht (?>x{m,n}).
Added in version 3.11.
\¶
Maskiert entweder besondere Zeichen (sodass du auf Zeichen wie '*', '?' und so weiter passen kannst) oder zeigt eine besondere Sequenz an. Besondere Sequenzen werden weiter unten behandelt.
Drückst du das Muster nicht als Raw-String aus, denke daran, dass Python den Backslash auch in Zeichenkettenliteralen für Escape-Sequenzen verwendet. Erkennt Pythons Parser die Escape-Sequenz nicht, landen der Backslash und das folgende Zeichen in der entstehenden Zeichenkette. Würde Python die entstehende Sequenz dagegen erkennen, sollte der Backslash verdoppelt werden. Das ist verwickelt und schwer zu durchschauen. Es wird daher sehr empfohlen, für alles außer den einfachsten Ausdrücken Raw-Strings zu verwenden.
[]¶
Gibt eine Menge von Zeichen an. In einer Menge gilt:
Zeichen lassen sich einzeln aufführen,
[amk]passt also auf'a','m'oder'k'.
Zeichenbereiche lassen sich angeben, indem man zwei Zeichen durch ein
'-'trennt:[a-z]passt auf jeden ASCII-Kleinbuchstaben,[0-5][0-9]auf alle zweistelligen Zahlen von00bis59und[0-9A-Fa-f]auf jede Hexadezimalziffer. Ist das-maskiert (etwa[a\-z]) oder steht es als erstes oder letztes Zeichen (etwa[-a]oder[a-]), passt es auf ein wörtliches'-'.Besondere Zeichen außer dem Backslash verlieren innerhalb von Mengen ihre besondere Bedeutung.
[(+*)]passt zum Beispiel auf jedes der wörtlichen Zeichen'(','+','*'oder')'.
Der Backslash maskiert entweder Zeichen, die in einer Menge besondere Bedeutung haben, etwa
'-',']','^'und'\\'selbst, oder zeigt eine besondere Sequenz an, die für ein einzelnes Zeichen steht (etwa\xa0oder\n) oder für eine Zeichenklasse (etwa\woder\S, weiter unten definiert). Beachte, dass\binnerhalb einer Menge für ein einzelnes „Backspace“-Zeichen steht und nicht für eine Wortgrenze wie außerhalb, und dass numerische Escapes wie\1dort immer oktale Escapes sind und keine Gruppenverweise. Besondere Sequenzen, die nicht auf ein einzelnes Zeichen passen, etwa\Aund\z, sind nicht erlaubt.
Um auf Zeichen zu passen, die nicht in einem Bereich liegen, komplementiert man die Menge. Ist das erste Zeichen der Menge
'^', passt sie auf alle Zeichen, die nicht in der Menge sind.[^5]passt zum Beispiel auf jedes Zeichen außer'5', und[^^]auf jedes Zeichen außer'^'. Steht^nicht an erster Stelle in der Menge, hat es keine besondere Bedeutung.Um in einer Menge auf ein wörtliches
']'zu passen, stelle einen Backslash davor oder setze es an den Anfang der Menge. So passen sowohl[()[\]{}]als auch[]()[{}]auf eine schließende eckige Klammer und ebenso auf eine öffnende eckige Klammer, auf geschweifte Klammern und auf runde Klammern.
Die Unterstützung verschachtelter Mengen und von Mengenoperationen wie im Unicode Technical Standard #18 kommt möglicherweise künftig hinzu. Das würde die Syntax ändern. Um diesen Wechsel zu erleichtern, wird in mehrdeutigen Fällen vorläufig eine
FutureWarningausgelöst. Dazu gehören Mengen, die mit einem wörtlichen'['beginnen oder die wörtlichen Zeichenfolgen'--','&&','~~'und'||'enthalten. Maskiere sie mit einem Backslash, um die Warnung zu vermeiden.
Geändert in Version 3.7: FutureWarning wird ausgelöst, wenn eine Zeichenmenge Konstrukte enthält, deren Bedeutung sich künftig ändern wird.
|¶
A|B, wobei A und B beliebige REs sein können, erzeugt einen regulären Ausdruck, der entweder auf A oder auf B passt. So lassen sich beliebig viele REs durch '|' trennen. Das ist auch innerhalb von Gruppen möglich (siehe unten). Beim Durchsuchen der Zielzeichenkette werden die durch '|' getrennten REs von links nach rechts probiert. Passt ein Muster vollständig, wird dieser Zweig angenommen. Hat A also einmal gepasst, wird B nicht weiter geprüft, selbst wenn es insgesamt eine längere Fundstelle ergäbe. Der Operator '|' ist mit anderen Worten nie gierig. Um auf ein wörtliches '|' zu passen, verwende \| oder schließe es in eine Zeichenklasse ein, etwa [|].
(...)¶
Passt auf den regulären Ausdruck innerhalb der Klammern und markiert Anfang und Ende einer Gruppe. Der Inhalt einer Gruppe lässt sich nach einem erfolgreichen Abgleich abrufen und später in der Zeichenkette mit der besonderen Sequenz \number erneut abgleichen (siehe unten). Um auf die wörtlichen Zeichen '(' oder ')' zu passen, verwende \( oder \) oder schließe sie in eine Zeichenklasse ein: [(], [)].
(?...)¶
Das ist eine Erweiterungsschreibweise (ein '?' nach einem '(' ist sonst bedeutungslos). Das erste Zeichen nach dem '?' bestimmt die Bedeutung und die weitere Syntax des Konstrukts. Erweiterungen erzeugen normalerweise keine neue Gruppe; (?P<name>...) ist die einzige Ausnahme von dieser Regel. Es folgen die derzeit unterstützten Erweiterungen.
(?aiLmsux)¶
(Ein oder mehrere Buchstaben aus der Menge 'a', 'i', 'L', 'm', 's', 'u', 'x'.) Die Gruppe passt auf die leere Zeichenkette. Die Buchstaben setzen die entsprechenden Flags für den gesamten regulären Ausdruck:
re.A(nur auf ASCII passen)re.I(Groß- und Kleinschreibung ignorieren)re.L(von der Locale abhängig)re.M(mehrzeilig)re.S(Punkt passt auf alles)re.U(auf Unicode passen)re.X(ausführlich)
(Die Flags sind unter Inhalt des Moduls beschrieben.) Das ist nützlich, wenn du die Flags Teil des regulären Ausdrucks sein lassen willst, statt der Funktion re.compile() ein Argument flag zu übergeben. Die Flags sollten am Anfang der Ausdruckszeichenkette stehen.
Geändert in Version 3.11: Dieses Konstrukt lässt sich nur am Anfang des Ausdrucks verwenden.
(?:...)¶
Eine nicht erfassende Fassung gewöhnlicher Klammern. Passt auf den regulären Ausdruck innerhalb der Klammern, die von der Gruppe erfasste Teilzeichenkette lässt sich danach aber nicht abrufen und auch später im Muster nicht ansprechen.
(?aiLmsux-imsx:...)¶
(Null oder mehr Buchstaben aus der Menge 'a', 'i', 'L', 'm', 's', 'u', 'x', optional gefolgt von '-' und einem oder mehreren Buchstaben aus 'i', 'm', 's', 'x'.) Die Buchstaben setzen oder entfernen die entsprechenden Flags für diesen Teil des Ausdrucks:
re.A(nur auf ASCII passen)re.I(Groß- und Kleinschreibung ignorieren)re.L(von der Locale abhängig)re.M(mehrzeilig)re.S(Punkt passt auf alles)re.U(auf Unicode passen)re.X(ausführlich)
(Die Flags sind unter Inhalt des Moduls beschrieben.)
Die Buchstaben 'a', 'L' und 'u' schließen sich als Inline-Flags gegenseitig aus, lassen sich also nicht kombinieren und nicht hinter '-' stellen. Erscheint einer von ihnen in einer Inline-Gruppe, setzt er stattdessen den Modus der umgebenden Gruppe außer Kraft. In Unicode-Mustern schaltet (?a:...) darauf um, nur auf ASCII zu passen, und (?u:...) auf Unicode (die Voreinstellung). In bytes-Mustern schaltet (?L:...) auf von der Locale abhängiges Passen um und (?a:...) darauf, nur auf ASCII zu passen (die Voreinstellung). Diese Außerkraftsetzung gilt nur für die eng umgrenzte Inline-Gruppe. Außerhalb der Gruppe gilt wieder der ursprüngliche Modus.
Added in version 3.6.
Geändert in Version 3.7: Die Buchstaben 'a', 'L' und 'u' lassen sich auch in einer Gruppe verwenden.
(?>...)¶
Versucht, auf ... zu passen, als wäre es ein eigener regulärer Ausdruck, und arbeitet bei Erfolg am restlichen Teil des Musters weiter. Passt das nachfolgende Muster nicht, kann der Stapel nur bis zu einem Punkt vor dem (?>...) zurückgerollt werden, denn der Ausdruck, bekannt als atomare Gruppe, hat beim Verlassen alle Stapelpunkte in seinem Inneren verworfen. (?>.*). würde daher nie etwas ergeben: Zuerst deckt .* alle möglichen Zeichen ab, dann bleibt nichts mehr übrig und das abschließende . geht leer aus. Da in der atomaren Gruppe keine Stapelpunkte gesichert sind und es auch davor keinen gibt, scheitert der gesamte Ausdruck.
Added in version 3.11.
(?P<name>...)¶
Ähnlich wie gewöhnliche Klammern, nur ist die von der Gruppe erfasste Teilzeichenkette über den symbolischen Gruppennamen name zugänglich. Gruppennamen müssen gültige Python-Bezeichner sein und dürfen in bytes-Mustern nur Bytes im ASCII-Bereich enthalten. Jeder Gruppenname darf innerhalb eines regulären Ausdrucks nur einmal definiert werden. Eine symbolische Gruppe ist zugleich eine numerierte Gruppe, genau als wäre sie nicht benannt.
Auf benannte Gruppen lässt sich in drei Zusammenhängen verweisen. Nehmen wir das Muster (?P<quote>['"]).*?(?P=quote) (es passt also auf eine Zeichenkette in einfachen oder doppelten Anführungszeichen):
Zusammenhang des Verweises auf die Gruppe „quote“ |
Möglichkeiten, darauf zu verweisen |
|---|---|
im Muster selbst |
|
beim Verarbeiten des Match-Objekts m |
|
in einer Zeichenkette, die dem Argument repl von |
|
Geändert in Version 3.12: In bytes-Mustern darf der Gruppenname name nur Bytes im ASCII-Bereich (b'\x00'-b'\x7f') enthalten.
(?P=name)¶
Ein Rückwärtsverweis auf eine benannte Gruppe. Er passt auf den Text, den die frühere Gruppe mit dem Namen name erfasst hat.
(?#...)¶
Ein Kommentar. Der Inhalt der Klammern wird einfach übergangen.
(?=...)¶
Passt, wenn ... als Nächstes passt, verbraucht aber nichts von der Zeichenkette. Das heißt Lookahead-Zusicherung. Isaac (?=Asimov) passt zum Beispiel nur dann auf 'Isaac ', wenn darauf 'Asimov' folgt.
(?!...)¶
Passt, wenn ... als Nächstes nicht passt. Das ist eine negative Lookahead-Zusicherung. Isaac (?!Asimov) passt zum Beispiel nur dann auf 'Isaac ', wenn darauf nicht 'Asimov' folgt.
(?<=...)¶
Passt, wenn der aktuellen Stelle in der Zeichenkette eine Fundstelle für ... vorausgeht, die an der aktuellen Stelle endet. Das heißt positive Lookbehind-Zusicherung. (?<=abc)def findet in 'abcdef' eine Fundstelle, denn das Lookbehind geht 3 Zeichen zurück und prüft, ob das enthaltene Muster passt. Das enthaltene Muster darf nur auf Zeichenketten einer festen Länge passen. abc oder a|b sind also erlaubt, a* und a{3,4} nicht. Beachte, dass Muster, die mit positiven Lookbehind-Zusicherungen beginnen, nicht am Anfang der durchsuchten Zeichenkette passen. Meist willst du dann die Funktion search() und nicht match() verwenden:
>>> import re
>>> m = re.search('(?<=abc)def', 'abcdef')
>>> m.group(0)
'def'
Dieses Beispiel sucht ein Wort nach einem Bindestrich:
>>> m = re.search(r'(?<=-)\w+', 'spam-egg')
>>> m.group(0)
'egg'
Geändert in Version 3.5: Unterstützung für Gruppenverweise mit fester Länge hinzugefügt.
(?<!...)¶
Passt, wenn der aktuellen Stelle in der Zeichenkette keine Fundstelle für ... vorausgeht. Das heißt negative Lookbehind-Zusicherung. Wie bei positiven Lookbehind-Zusicherungen darf das enthaltene Muster nur auf Zeichenketten einer festen Länge passen. Muster, die mit negativen Lookbehind-Zusicherungen beginnen, können am Anfang der durchsuchten Zeichenkette passen.
(?(id/name)yes-pattern|no-pattern)¶
Versucht, auf yes-pattern zu passen, wenn die Gruppe mit der id oder dem name vorhanden ist, und sonst auf no-pattern. no-pattern ist optional und kann weggelassen werden. (<)?(\w+@\w+(?:\.\w+)+)(?(1)>|$) ist zum Beispiel ein schlechtes Muster für E-Mail-Adressen: Es passt auf '<user@host.com>' ebenso wie auf 'user@host.com', aber weder auf '<user@host.com' noch auf 'user@host.com>' in voller Länge (re.search() findet im ersten Fall nur 'user@host.com').
Geändert in Version 3.12: Die Gruppenkennung id darf nur ASCII-Ziffern enthalten. In bytes-Mustern darf der Gruppenname name nur Bytes im ASCII-Bereich (b'\x00'-b'\x7f') enthalten.
Besondere Sequenzen¶
Die besonderen Sequenzen bestehen aus '\' und einem Zeichen aus der folgenden Liste. Ist das gewöhnliche Zeichen keine ASCII-Ziffer und kein ASCII-Buchstabe, passt der entstehende RE auf das zweite Zeichen. \$ passt zum Beispiel auf das Zeichen '$'.
\number¶
Passt auf den Inhalt der Gruppe mit derselben Nummer. Gruppen werden ab 1 numeriert. (.+) \1 passt zum Beispiel auf 'the the' oder '55 55', nicht aber auf 'thethe' (beachte das Leerzeichen nach der Gruppe). Mit dieser besonderen Sequenz lässt sich nur auf eine der ersten 99 Gruppen verweisen. Ist die erste Ziffer von number eine 0 oder ist number 3 Oktalziffern lang, wird sie nicht als Gruppenverweis gedeutet, sondern als das Zeichen mit dem Oktalwert number. Zwischen '[' und ']' einer Zeichenklasse gelten alle numerischen Escapes als Zeichen.
\A¶
Passt nur am Anfang der Zeichenkette.
\b¶
Passt auf die leere Zeichenkette, aber nur am Anfang oder Ende eines Wortes. Ein Wort ist als Folge von Wortzeichen definiert. Beachte, dass \b formal als Grenze zwischen einem \w- und einem \W-Zeichen (oder umgekehrt) oder zwischen \w und dem Anfang oder Ende der Zeichenkette definiert ist. r'\bat\b' passt also auf 'at', 'at.', '(at)' und 'as at ay', nicht aber auf 'attempt' oder 'atlas'.
Die voreingestellten Wortzeichen in Unicode-Mustern (str) sind die alphanumerischen Unicode-Zeichen und der Unterstrich. Mit dem Flag ASCII lässt sich das ändern. Wortgrenzen richten sich nach der aktuellen Locale, wenn das Flag LOCALE verwendet wird.
Bemerkung
Innerhalb eines Zeichenbereichs steht \b für das Backspace-Zeichen, aus Kompatibilität mit Pythons Zeichenkettenliteralen.
\B¶
Passt auf die leere Zeichenkette, aber nur dann, wenn sie nicht am Anfang oder Ende eines Wortes steht. r'at\B' passt also auf 'athens', 'atom', 'attorney', nicht aber auf 'at', 'at.' oder 'at!'. \B ist das Gegenteil von \b. Die Wortzeichen in Unicode-Mustern (str) sind daher die alphanumerischen Unicode-Zeichen oder der Unterstrich, was sich aber mit dem Flag ASCII ändern lässt. Wortgrenzen richten sich nach der aktuellen Locale, wenn das Flag LOCALE verwendet wird.
Geändert in Version 3.14: \B passt jetzt auf die leere Eingabezeichenkette.
\d¶
- Für Unicode-Muster (str):
Passt auf jede dezimale Unicode-Ziffer (also auf jedes Zeichen der Unicode-Zeichenkategorie [Nd]). Dazu gehören
[0-9]und viele weitere Ziffernzeichen.Passt auf
[0-9], wenn das FlagASCIIverwendet wird.- Für 8-Bit-Muster (bytes):
Passt auf jede Dezimalziffer im ASCII-Zeichensatz. Das entspricht
[0-9].
\D¶
Passt auf jedes Zeichen, das keine Dezimalziffer ist. Das ist das Gegenteil von \d.
Passt auf [^0-9], wenn das Flag ASCII verwendet wird.
\s¶
- Für Unicode-Muster (str):
Passt auf Unicode-Leerraumzeichen (wie von
str.isspace()definiert). Dazu gehören[ \t\n\r\f\v]und viele weitere Zeichen, zum Beispiel die geschützten Leerzeichen, die die Typografieregeln vieler Sprachen vorschreiben.Passt auf
[ \t\n\r\f\v], wenn das FlagASCIIverwendet wird.- Für 8-Bit-Muster (bytes):
Passt auf die Zeichen, die im ASCII-Zeichensatz als Leerraum gelten. Das entspricht
[ \t\n\r\f\v].
\S¶
Passt auf jedes Zeichen, das kein Leerraumzeichen ist. Das ist das Gegenteil von \s.
Passt auf [^ \t\n\r\f\v], wenn das Flag ASCII verwendet wird.
\w¶
- Für Unicode-Muster (str):
Passt auf Unicode-Wortzeichen. Dazu gehören alle alphanumerischen Unicode-Zeichen (wie von
str.isalnum()definiert) sowie der Unterstrich (_).Passt auf
[a-zA-Z0-9_], wenn das FlagASCIIverwendet wird.- Für 8-Bit-Muster (bytes):
Passt auf die Zeichen, die im ASCII-Zeichensatz als alphanumerisch gelten. Das entspricht
[a-zA-Z0-9_]. Wird das FlagLOCALEverwendet, passt es auf die Zeichen, die in der aktuellen Locale als alphanumerisch gelten, und auf den Unterstrich.
\W¶
Passt auf jedes Zeichen, das kein Wortzeichen ist. Das ist das Gegenteil von \w. Voreingestellt passt es auf Zeichen außer dem Unterstrich (_), für die str.isalnum() False zurückgibt.
Passt auf [^a-zA-Z0-9_], wenn das Flag ASCII verwendet wird.
Wird das Flag LOCALE verwendet, passt es auf die Zeichen, die in der aktuellen Locale weder alphanumerisch sind noch der Unterstrich.
\z¶
Passt nur am Ende der Zeichenkette.
Added in version 3.14.
\Z¶
Dasselbe wie \z. Aus Kompatibilität mit alten Python-Versionen.
Standard-Escapes¶
Die meisten Escape-Sequenzen, die Python-Zeichenkettenliterale unterstützen, nimmt auch der Parser für reguläre Ausdrücke an:
\a \b \f \n
\N \r \t \u
\U \v \x \\
(Beachte, dass \b für Wortgrenzen steht und nur innerhalb von Zeichenklassen „Backspace“ bedeutet.)
Die Escape-Sequenzen '\u', '\U' und '\N' werden nur in Unicode-Mustern (str) erkannt. In bytes-Mustern sind sie Fehler. Unbekannte Escapes von ASCII-Buchstaben sind für die künftige Verwendung vorbehalten und gelten als Fehler.
Oktale Escapes sind in eingeschränkter Form enthalten. Ist die erste Ziffer eine 0 oder stehen drei Oktalziffern da, gilt es als oktales Escape. Andernfalls ist es ein Gruppenverweis. Wie bei Zeichenkettenliteralen sind oktale Escapes immer höchstens drei Ziffern lang.
Geändert in Version 3.3: Die Escape-Sequenzen '\u' und '\U' kamen hinzu.
Geändert in Version 3.6: Unbekannte Escapes aus '\' und einem ASCII-Buchstaben sind jetzt Fehler.
Geändert in Version 3.8: Die Escape-Sequenz '\N{name}' kam hinzu. Wie in Zeichenkettenliteralen wird sie zum benannten Unicode-Zeichen erweitert, etwa '\N{EM DASH}'.
Inhalt des Moduls¶
Das Modul definiert mehrere Funktionen, Konstanten und eine Ausnahme. Einige der Funktionen sind vereinfachte Fassungen der vollwertigen Methoden kompilierter regulärer Ausdrücke. Die meisten nicht ganz einfachen Anwendungen verwenden immer die kompilierte Form.
Flags¶
Geändert in Version 3.6: Flag-Konstanten sind jetzt Instanzen von RegexFlag, einer Unterklasse von enum.IntFlag.
- class re.RegexFlag¶
Eine
enum.IntFlag-Klasse, die die unten aufgeführten Regex-Optionen enthält.Added in version 3.11: - added to
__all__
- re.A¶
- re.ASCII¶
Lässt
\w,\W,\b,\B,\d,\D,\sund\Snur auf ASCII passen statt auf vollständiges Unicode. Das ist nur für Unicode-Muster (str) von Bedeutung und wird bei bytes-Mustern übergangen.Entspricht dem Inline-Flag
(?a).
- re.DEBUG¶
Zeigt Informationen zur Fehlersuche über den kompilierten Ausdruck an.
Kein entsprechendes Inline-Flag.
- re.I¶
- re.IGNORECASE¶
Passt ohne Beachtung der Groß- und Kleinschreibung; Ausdrücke wie
[A-Z]passen dann auch auf Kleinbuchstaben. Das vollständige Passen über Unicode hinweg (etwaÜaufü) funktioniert ebenfalls, sofern nicht das FlagASCIITreffer außerhalb von ASCII abschaltet. Die aktuelle Locale ändert die Wirkung dieses Flags nur dann, wenn auch das FlagLOCALEverwendet wird.Entspricht dem Inline-Flag
(?i).Beachte: Werden die Unicode-Muster
[a-z]oder[A-Z]mit dem FlagIGNORECASEverwendet, passen sie auf die 52 ASCII-Buchstaben und auf 4 weitere Buchstaben außerhalb von ASCII: ‚İ‘ (U+0130, lateinischer Großbuchstabe I mit Punkt darüber), ‚ı‘ (U+0131, lateinischer Kleinbuchstabe i ohne Punkt), ‚ſ‘ (U+017F, lateinischer Kleinbuchstabe langes s) und ‚K‘ (U+212A, Kelvin-Zeichen). Wird das FlagASCIIverwendet, wird nur auf die Buchstaben ‚a‘ bis ‚z‘ und ‚A‘ bis ‚Z‘ gepasst.
- re.L¶
- re.LOCALE¶
Macht
\w,\W,\b,\Bund das Passen ohne Beachtung der Groß- und Kleinschreibung von der aktuellen Locale abhängig. Dieses Flag lässt sich nur mit bytes-Mustern verwenden.Entspricht dem Inline-Flag
(?L).Warnung
Von diesem Flag wird abgeraten. Ziehe stattdessen das Passen auf Unicode in Erwägung. Der Locale-Mechanismus ist sehr unzuverlässig, da er nur einen „Kulturraum“ auf einmal behandelt und nur mit 8-Bit-Locales funktioniert. Bei Unicode-Mustern (str) ist das Passen auf Unicode voreingestellt eingeschaltet und kann mit verschiedenen Locales und Sprachen umgehen.
Geändert in Version 3.6:
LOCALElässt sich nur mit bytes-Mustern verwenden und ist nicht mitASCIIvereinbar.Geändert in Version 3.7: Kompilierte Objekte regulärer Ausdrücke mit dem Flag
LOCALEhängen nicht mehr von der Locale zur Kompilierzeit ab. Nur die Locale zum Zeitpunkt des Abgleichs beeinflusst das Ergebnis.
- re.M¶
- re.MULTILINE¶
Ist dieses Flag gesetzt, passt das Musterzeichen
'^'am Anfang der Zeichenkette und am Anfang jeder Zeile (unmittelbar nach jedem Zeilenumbruch), und das Musterzeichen'$'passt am Ende der Zeichenkette und am Ende jeder Zeile (unmittelbar vor jedem Zeilenumbruch). Voreingestellt passt'^'nur am Anfang der Zeichenkette und'$'nur am Ende der Zeichenkette und unmittelbar vor dem Zeilenumbruch am Ende der Zeichenkette, sofern es einen gibt.Entspricht dem Inline-Flag
(?m).
- re.NOFLAG¶
Zeigt an, dass kein Flag angewendet wird. Der Wert ist
0. Dieses Flag lässt sich als voreingestellter Wert für ein Schlüsselwortargument einer Funktion verwenden oder als Ausgangswert, der bedingt mit anderen Flags per OR verknüpft wird. Beispiel für die Verwendung als voreingestellter Wert:def myfunc(pattern, text, flag=re.NOFLAG): return re.search(pattern, text, flag)
Added in version 3.11.
- re.S¶
- re.DOTALL¶
Lässt das besondere Zeichen
'.'auf jedes Zeichen überhaupt passen, auch auf einen Zeilenumbruch. Ohne dieses Flag passt'.'auf alles außer einem Zeilenumbruch.Entspricht dem Inline-Flag
(?s).
- re.U¶
- re.UNICODE¶
In Python 3 wird bei
str-Mustern voreingestellt auf Unicode-Zeichen gepasst. Dieses Flag ist daher überflüssig und ohne Wirkung. Es bleibt nur aus Gründen der Rückwärtskompatibilität erhalten.Mit
ASCIIlässt sich das Passen stattdessen auf ASCII-Zeichen beschränken.
- re.X¶
- re.VERBOSE¶
Mit diesem Flag kannst du reguläre Ausdrücke schreiben, die schöner aussehen und besser lesbar sind, denn du darfst logische Abschnitte des Musters sichtbar trennen und Kommentare einfügen. Leerraum innerhalb des Musters wird übergangen, außer in einer Zeichenklasse, hinter einem nicht maskierten Backslash oder innerhalb von Tokens wie
*?,(?:oder(?P<...>. So sind(? :und* ?nicht erlaubt. Enthält eine Zeile ein#, das nicht in einer Zeichenklasse steht und dem kein nicht maskierter Backslash vorausgeht, werden alle Zeichen vom linkesten solchen#bis zum Zeilenende übergangen.Die beiden folgenden Objekte regulärer Ausdrücke, die auf eine Dezimalzahl passen, sind daher funktional gleich:
a = re.compile(r"""\d + # the integral part \. # the decimal point \d * # some fractional digits""", re.X) b = re.compile(r"\d+\.\d*")
Entspricht dem Inline-Flag
(?x).
Funktionen¶
- re.compile(pattern, flags=0)¶
Kompiliert ein Muster eines regulären Ausdrucks zu einem Objekt eines regulären Ausdrucks, mit dem sich über seine Methoden
prefixmatch(),search()und die weiteren unten beschriebenen Methoden abgleichen lässt.Das Verhalten des Ausdrucks lässt sich über einen Wert für flags ändern. Als Werte dienen die Variablen unter flags, bitweise mit OR (dem Operator
|) verknüpft.Die Folge
prog = re.compile(pattern) result = prog.search(string)
ist gleichbedeutend mit
result = re.search(pattern, string)
aber
re.compile()zu verwenden und das entstehende Objekt des regulären Ausdrucks zur Wiederverwendung zu behalten ist effizienter, wenn der Ausdruck in einem Programm mehrmals verwendet wird.Bemerkung
Die kompilierten Fassungen der zuletzt an
re.compile()und an die Funktionen auf Modulebene übergebenen Muster werden zwischengespeichert. Programme, die jeweils nur wenige reguläre Ausdrücke verwenden, müssen sich daher nicht um das Kompilieren kümmern.
- re.search(pattern, string, flags=0)¶
Durchsucht string nach der ersten Stelle, an der der reguläre Ausdruck pattern passt, und gibt ein passendes
Matchzurück. GibtNonezurück, wenn keine Stelle der Zeichenkette auf das Muster passt. Beachte, dass das etwas anderes ist, als irgendwo in der Zeichenkette eine Fundstelle der Länge null zu finden.Das Verhalten des Ausdrucks lässt sich über einen Wert für flags ändern. Als Werte dienen die Variablen unter flags, bitweise mit OR (dem Operator
|) verknüpft.
- re.prefixmatch(pattern, string, flags=0)¶
Passen null oder mehr Zeichen am Anfang von string auf den regulären Ausdruck pattern, wird ein passendes
Matchzurückgegeben. GibtNonezurück, wenn die Zeichenkette nicht auf das Muster passt. Beachte, dass das etwas anderes ist als eine Fundstelle der Länge null.Bemerkung
Selbst im
MULTILINE-Modus passt das nur am Anfang der Zeichenkette und nicht am Anfang jeder Zeile.Willst du eine Fundstelle irgendwo in string finden, verwende stattdessen
search()(siehe auch search() gegenüber prefixmatch()).Das Verhalten des Ausdrucks lässt sich über einen Wert für flags ändern. Als Werte dienen die Variablen unter flags, bitweise mit OR (dem Operator
|) verknüpft.Diese Funktion hat jetzt zwei Namen und ist lange als
match()bekannt. Verwende diesen Namen, wenn du Kompatibilität mit älteren Python-Versionen brauchst.Added in version 3.15.
- re.match(pattern, string, flags=0)¶
Sanft abgekündigt <Soft deprecated> seit Version 3.15:
match()ist soft deprecated zugunsten des anderen Namensprefixmatch()dieser API, der ausdrücklich beschreibt, was geschieht. Verwende ihn, um die Absicht klarer auszudrücken. In anderen Sprachen und Umsetzungen regulärer Ausdrücke ist es üblich, den Begriff match für das Verhalten zu verwenden, das Python immersearch()genannt hat. Siehe prefixmatch() gegenüber match().
- re.fullmatch(pattern, string, flags=0)¶
Passt die ganze Zeichenkette string auf den regulären Ausdruck pattern, wird ein passendes
Matchzurückgegeben. GibtNonezurück, wenn die Zeichenkette nicht auf das Muster passt. Beachte, dass das etwas anderes ist als eine Fundstelle der Länge null.Das Verhalten des Ausdrucks lässt sich über einen Wert für flags ändern. Als Werte dienen die Variablen unter flags, bitweise mit OR (dem Operator
|) verknüpft.Added in version 3.4.
- re.split(pattern, string, maxsplit=0, flags=0)¶
Teilt string an den Vorkommen von pattern. Werden in pattern erfassende Klammern verwendet, wird auch der Text aller Gruppen des Musters Teil der entstehenden Liste. Ist maxsplit ungleich null, finden höchstens maxsplit Teilungen statt und der Rest der Zeichenkette wird als letztes Element der Liste zurückgegeben.
>>> re.split(r'\W+', 'Words, words, words.') ['Words', 'words', 'words', ''] >>> re.split(r'(\W+)', 'Words, words, words.') ['Words', ', ', 'words', ', ', 'words', '.', ''] >>> re.split(r'\W+', 'Words, words, words.', maxsplit=1) ['Words', 'words, words.'] >>> re.split('[a-f]+', '0a3B9', flags=re.IGNORECASE) ['0', '3', '9']
Gibt es im Trenner erfassende Gruppen und passt er am Anfang der Zeichenkette, beginnt das Ergebnis mit einer leeren Zeichenkette. Dasselbe gilt für das Ende der Zeichenkette:
>>> re.split(r'(\W+)', '...words, words...') ['', '...', 'words', ', ', 'words', '...', '']
So stehen die Bestandteile des Trenners immer an denselben relativen Positionen in der Ergebnisliste.
Unmittelbar benachbarte leere Fundstellen sind nicht möglich, eine leere Fundstelle kann aber unmittelbar auf eine nicht leere folgen.
>>> re.split(r'\b', 'Words, words, words.') ['', 'Words', ', ', 'words', ', ', 'words', '.'] >>> re.split(r'\W*', '...words...') ['', '', 'w', 'o', 'r', 'd', 's', '', ''] >>> re.split(r'(\W*)', '...words...') ['', '...', '', '', 'w', '', 'o', '', 'r', '', 'd', '', 's', '...', '', '', '']
Das Verhalten des Ausdrucks lässt sich über einen Wert für flags ändern. Als Werte dienen die Variablen unter flags, bitweise mit OR (dem Operator
|) verknüpft.Geändert in Version 3.1: Das optionale Argument flags kam hinzu.
Geändert in Version 3.7: Unterstützung für das Teilen an einem Muster hinzugefügt, das auf eine leere Zeichenkette passen könnte.
Veraltet ab Version 3.13: maxsplit und flags als positionsbezogene Argumente zu übergeben ist veraltet. In künftigen Python-Versionen werden sie nur als Schlüsselwort übergebbare Parameter sein.
- re.findall(pattern, string, flags=0)¶
Gibt alle einander nicht überlappenden Fundstellen von pattern in string als Liste von Zeichenketten oder Tupeln zurück. string wird von links nach rechts durchsucht und die Fundstellen werden in der Reihenfolge ihres Auftretens zurückgegeben. Leere Fundstellen gehören zum Ergebnis.
Das Ergebnis hängt von der Anzahl der erfassenden Gruppen im Muster ab. Gibt es keine Gruppen, wird eine Liste der Zeichenketten zurückgegeben, die auf das gesamte Muster passen. Gibt es genau eine Gruppe, wird eine Liste der Zeichenketten zurückgegeben, die auf diese Gruppe passen. Gibt es mehrere Gruppen, wird eine Liste von Tupeln der Zeichenketten zurückgegeben, die auf die Gruppen passen. Nicht erfassende Gruppen beeinflussen die Form des Ergebnisses nicht.
>>> re.findall(r'\bf[a-z]*', 'which foot or hand fell fastest') ['foot', 'fell', 'fastest'] >>> re.findall(r'(\w+)=(\d+)', 'set width=20 and height=10') [('width', '20'), ('height', '10')]
Das Verhalten des Ausdrucks lässt sich über einen Wert für flags ändern. Als Werte dienen die Variablen unter flags, bitweise mit OR (dem Operator
|) verknüpft.Geändert in Version 3.7: Nicht leere Fundstellen können jetzt unmittelbar nach einer vorigen leeren Fundstelle beginnen.
- re.finditer(pattern, string, flags=0)¶
Gibt einen Iterator zurück, der
Match-Objekte für alle einander nicht überlappenden Fundstellen des RE pattern in string liefert. string wird von links nach rechts durchsucht und die Fundstellen werden in der Reihenfolge ihres Auftretens zurückgegeben. Leere Fundstellen gehören zum Ergebnis.Das Verhalten des Ausdrucks lässt sich über einen Wert für flags ändern. Als Werte dienen die Variablen unter flags, bitweise mit OR (dem Operator
|) verknüpft.Geändert in Version 3.7: Nicht leere Fundstellen können jetzt unmittelbar nach einer vorigen leeren Fundstelle beginnen.
- re.sub(pattern, repl, string, count=0, flags=0)¶
Gibt die Zeichenkette zurück, die entsteht, wenn die am weitesten links stehenden, einander nicht überlappenden Vorkommen von pattern in string durch den Ersatz repl ersetzt werden. Wird das Muster nicht gefunden, wird string unverändert zurückgegeben. repl kann eine Zeichenkette oder eine Funktion sein. Ist es eine Zeichenkette, werden darin enthaltene Backslash-Escapes verarbeitet.
\nwird also in einen einzelnen Zeilenumbruch umgewandelt,\rin einen Wagenrücklauf und so weiter. Unbekannte Escapes von ASCII-Buchstaben sind für die künftige Verwendung vorbehalten und gelten als Fehler. Andere unbekannte Escapes wie\&bleiben unangetastet. Rückwärtsverweise wie\6werden durch die Teilzeichenkette ersetzt, die Gruppe 6 im Muster erfasst hat. Zum Beispiel:>>> re.sub(r'def\s+([a-zA-Z_][a-zA-Z_0-9]*)\s*\(\s*\):', ... r'static PyObject*\npy_\1(void)\n{', ... 'def myfunc():') 'static PyObject*\npy_myfunc(void)\n{'
Ist repl eine Funktion, wird sie für jedes einander nicht überlappende Vorkommen von pattern aufgerufen. Die Funktion nimmt ein einziges
Match-Argument und gibt die Ersatzzeichenkette zurück. Zum Beispiel:>>> def dashrepl(matchobj): ... if matchobj.group(0) == '-': return ' ' ... else: return '-' ... >>> re.sub('-{1,2}', dashrepl, 'pro----gram-files') 'pro--gram files' >>> re.sub(r'\sAND\s', ' & ', 'Baked Beans And Spam', flags=re.IGNORECASE) 'Baked Beans & Spam'
Das Muster kann eine Zeichenkette oder ein
Patternsein.Das optionale Argument count ist die größte Anzahl zu ersetzender Vorkommen des Musters; count muss eine nicht negative ganze Zahl sein. Wird es weggelassen oder ist es null, werden alle Vorkommen ersetzt.
Unmittelbar benachbarte leere Fundstellen sind nicht möglich, eine leere Fundstelle kann aber unmittelbar auf eine nicht leere folgen. Daher gibt
sub('x*', '-', 'abxd')'-a-b--d-'statt'-a-b-d-'zurück.In repl-Argumenten vom Typ Zeichenkette verwendet
\g<name>neben den oben beschriebenen Zeichen-Escapes und Rückwärtsverweisen die Teilzeichenkette, die die Gruppe mit dem Namennameerfasst hat, wie mit der Syntax(?P<name>...)festgelegt.\g<number>verwendet die entsprechende Gruppennummer;\g<2>entspricht daher\2, ist in einem Ersatz wie\g<2>0aber nicht mehrdeutig.\20würde als Verweis auf Gruppe 20 gedeutet und nicht als Verweis auf Gruppe 2 gefolgt vom wörtlichen Zeichen'0'. Der Rückwärtsverweis\g<0>setzt die gesamte Teilzeichenkette ein, auf die der RE gepasst hat.Das Verhalten des Ausdrucks lässt sich über einen Wert für flags ändern. Als Werte dienen die Variablen unter flags, bitweise mit OR (dem Operator
|) verknüpft.Geändert in Version 3.1: Das optionale Argument flags kam hinzu.
Geändert in Version 3.5: Gruppen ohne Fundstelle werden durch eine leere Zeichenkette ersetzt.
Geändert in Version 3.6: Unbekannte Escapes in pattern aus
'\'und einem ASCII-Buchstaben sind jetzt Fehler.Geändert in Version 3.7: Unbekannte Escapes in repl aus
'\'und einem ASCII-Buchstaben sind jetzt Fehler. Eine leere Fundstelle kann unmittelbar auf eine nicht leere folgen.Geändert in Version 3.12: Die Gruppenkennung id darf nur ASCII-Ziffern enthalten. In
bytes-Ersatzzeichenketten darf der Gruppenname name nur Bytes im ASCII-Bereich (b'\x00'-b'\x7f') enthalten.Veraltet ab Version 3.13: count und flags als positionsbezogene Argumente zu übergeben ist veraltet. In künftigen Python-Versionen werden sie nur als Schlüsselwort übergebbare Parameter sein.
- re.subn(pattern, repl, string, count=0, flags=0)¶
Führt dieselbe Operation wie
sub()aus, gibt aber ein Tupel(new_string, number_of_subs_made)zurück.Das Verhalten des Ausdrucks lässt sich über einen Wert für flags ändern. Als Werte dienen die Variablen unter flags, bitweise mit OR (dem Operator
|) verknüpft.
- re.escape(pattern)¶
Maskiert besondere Zeichen in pattern. Das ist nützlich, wenn du auf eine beliebige wörtliche Zeichenkette passen willst, die Metazeichen regulärer Ausdrücke enthalten kann. Zum Beispiel:
>>> print(re.escape('https://www.python.org')) https://www\.python\.org >>> legal_chars = string.ascii_lowercase + string.digits + "!#$%&'*+-.^_`|~:" >>> print('[%s]+' % re.escape(legal_chars)) [abcdefghijklmnopqrstuvwxyz0123456789!\#\$%\&'\*\+\-\.\^_`\|\~:]+ >>> operators = ['+', '-', '*', '/', '**'] >>> print('|'.join(map(re.escape, sorted(operators, reverse=True)))) /|\-|\+|\*\*|\*
Diese Funktion darf nicht für die Ersatzzeichenkette in
sub()undsubn()verwendet werden. Dort sollten nur Backslashes maskiert werden. Zum Beispiel:>>> digits_re = r'\d+' >>> sample = '/usr/sbin/sendmail - 0 errors, 12 warnings' >>> print(re.sub(digits_re, digits_re.replace('\\', r'\\'), sample)) /usr/sbin/sendmail - \d+ errors, \d+ warnings
Geändert in Version 3.3: Das Zeichen
'_'wird nicht mehr maskiert.Geändert in Version 3.7: Es werden nur die Zeichen maskiert, die in einem regulären Ausdruck besondere Bedeutung haben können. Daher werden
'!','"','%',"'",',','/',':',';','<','=','>','@'und"`"nicht mehr maskiert.
- re.purge()¶
Leert den Zwischenspeicher für reguläre Ausdrücke.
Ausnahmen¶
- exception re.PatternError(msg, pattern=None, pos=None)¶
Ausnahme, die ausgelöst wird, wenn eine an eine der hiesigen Funktionen übergebene Zeichenkette kein gültiger regulärer Ausdruck ist (sie kann etwa unpaarige Klammern enthalten) oder wenn beim Kompilieren oder Abgleichen ein anderer Fehler auftritt. Dass eine Zeichenkette keine Fundstelle für ein Muster enthält, ist nie ein Fehler. Die
PatternError-Instanz hat die folgenden zusätzlichen Attribute:- msg¶
Die unformatierte Fehlermeldung.
- pattern¶
Das Muster des regulären Ausdrucks.
- pos¶
Der Index in pattern, an dem das Kompilieren fehlschlug (kann
Nonesein).
- lineno¶
Die Zeile, die zu pos gehört (kann
Nonesein).
- colno¶
Die Spalte, die zu pos gehört (kann
Nonesein).
Geändert in Version 3.5: Zusätzliche Attribute kamen hinzu.
Geändert in Version 3.13:
PatternErrorhieß ursprünglicherror. Dieser Name bleibt aus Gründen der Rückwärtskompatibilität als Alias erhalten.
Objekte regulärer Ausdrücke¶
- class re.Pattern¶
Kompiliertes Objekt eines regulären Ausdrucks, wie
re.compile()es zurückgibt.Muster sind generisch über den Typ der Zeichenkette, mit der sie umgehen (
stroderbytes).Geändert in Version 3.9:
re.Patternunterstützt[], um ein Unicode-Muster (str) oder ein bytes-Muster anzugeben. Siehe Generic-Alias-Typ.
- Pattern.search(string[, pos[, endpos]])¶
Durchsucht string nach der ersten Stelle, an der dieser reguläre Ausdruck passt, und gibt ein passendes
Matchzurück. GibtNonezurück, wenn keine Stelle der Zeichenkette auf das Muster passt. Beachte, dass das etwas anderes ist, als irgendwo in der Zeichenkette eine Fundstelle der Länge null zu finden.Der optionale zweite Parameter pos gibt den Index in der Zeichenkette an, an dem die Suche beginnen soll. Voreingestellt ist
0. Das entspricht nicht ganz einem Abschnitt der Zeichenkette: Das Musterzeichen'^'passt am wirklichen Anfang der Zeichenkette und an den Stellen unmittelbar nach einem Zeilenumbruch, nicht aber zwangsläufig an dem Index, an dem die Suche beginnt.Der optionale Parameter endpos begrenzt, wie weit die Zeichenkette durchsucht wird. Es verhält sich so, als wäre die Zeichenkette endpos Zeichen lang, es werden also nur die Zeichen von pos bis
endpos - 1durchsucht. Ist endpos kleiner als pos, wird keine Fundstelle gefunden. Andernfalls entsprichtrx.search(string, 0, 50)dem Aufrufrx.search(string[:50], 0), wenn rx ein kompiliertes Objekt eines regulären Ausdrucks ist.>>> pattern = re.compile("d") >>> pattern.search("dog") # Match at index 0 <re.Match object; span=(0, 1), match='d'> >>> pattern.search("dog", 1) # No match; search doesn't include the "d"
- Pattern.prefixmatch(string[, pos[, endpos]])¶
Passen null oder mehr Zeichen am Anfang von string auf diesen regulären Ausdruck, wird ein passendes
Matchzurückgegeben. GibtNonezurück, wenn die Zeichenkette nicht auf das Muster passt. Beachte, dass das etwas anderes ist als eine Fundstelle der Länge null.Beachte, dass das selbst im
MULTILINE-Modus nur am Anfang der Zeichenkette passt und nicht am Anfang jeder Zeile.Die optionalen Parameter pos und endpos haben dieselbe Bedeutung wie bei der Methode
search().>>> pattern = re.compile("o") >>> pattern.prefixmatch("dog") # No match as "o" is not at the start of "dog". >>> pattern.prefixmatch("dog", 1) # Match as "o" is the 2nd character of "dog". <re.Match object; span=(1, 2), match='o'>
Willst du eine Fundstelle irgendwo in string finden, verwende stattdessen
search()(siehe auch search() gegenüber prefixmatch()).Diese Methode hat jetzt zwei Namen und ist lange als
match()bekannt. Verwende diesen Namen, wenn du Kompatibilität mit älteren Python-Versionen brauchst.Added in version 3.15.
- Pattern.match(string[, pos[, endpos]])¶
Sanft abgekündigt <Soft deprecated> seit Version 3.15:
match()ist soft deprecated zugunsten des anderen Namensprefixmatch()dieser API, der ausdrücklich beschreibt, was geschieht. Verwende ihn, um die Absicht klarer auszudrücken. In anderen Sprachen und Umsetzungen regulärer Ausdrücke ist es üblich, den Begriff match für das Verhalten zu verwenden, das Python immersearch()genannt hat. Siehe prefixmatch() gegenüber match().
- Pattern.fullmatch(string[, pos[, endpos]])¶
Passt die ganze Zeichenkette string auf diesen regulären Ausdruck, wird ein passendes
Matchzurückgegeben. GibtNonezurück, wenn die Zeichenkette nicht auf das Muster passt. Beachte, dass das etwas anderes ist als eine Fundstelle der Länge null.Die optionalen Parameter pos und endpos haben dieselbe Bedeutung wie bei der Methode
search().>>> pattern = re.compile("o[gh]") >>> pattern.fullmatch("dog") # No match as "o" is not at the start of "dog". >>> pattern.fullmatch("ogre") # No match as not the full string matches. >>> pattern.fullmatch("doggie", 1, 3) # Matches within given limits. <re.Match object; span=(1, 3), match='og'>
Added in version 3.4.
- Pattern.split(string, maxsplit=0)¶
Gleichbedeutend mit der Funktion
split(), mit dem kompilierten Muster.
- Pattern.findall(string[, pos[, endpos]])¶
Ähnlich der Funktion
findall(), mit dem kompilierten Muster, nimmt aber auch die optionalen Parameter pos und endpos an, die den Suchbereich wie beisearch()begrenzen.
- Pattern.finditer(string[, pos[, endpos]])¶
Ähnlich der Funktion
finditer(), mit dem kompilierten Muster, nimmt aber auch die optionalen Parameter pos und endpos an, die den Suchbereich wie beisearch()begrenzen.
- Pattern.sub(repl, string, count=0)¶
Gleichbedeutend mit der Funktion
sub(), mit dem kompilierten Muster.
- Pattern.subn(repl, string, count=0)¶
Gleichbedeutend mit der Funktion
subn(), mit dem kompilierten Muster.
- Pattern.flags¶
Die Flags für den Abgleich. Das ist eine Kombination der an
compile()übergebenen Flags, aller(?...)-Inline-Flags im Muster und impliziter Flags wieUNICODE, wenn das Muster eine Unicode-Zeichenkette ist.
- Pattern.groups¶
Die Anzahl der erfassenden Gruppen im Muster.
- Pattern.groupindex¶
Ein Dictionary, das die mit
(?P<id>)festgelegten symbolischen Gruppennamen auf Gruppennummern abbildet. Das Dictionary ist leer, wenn im Muster keine symbolischen Gruppen verwendet wurden.
- Pattern.pattern¶
Die Musterzeichenkette, aus der das Musterobjekt kompiliert wurde.
Geändert in Version 3.7: Unterstützung für copy.copy() und copy.deepcopy() hinzugefügt. Kompilierte Objekte regulärer Ausdrücke gelten als atomar.
Match-Objekte¶
Match-Objekte haben immer den Wahrheitswert True. Da match() und search() None zurückgeben, wenn es keine Fundstelle gibt, kannst du mit einer einfachen if-Anweisung prüfen, ob es eine gab:
if match := re.search(pattern, string):
process(match)
- class re.Match¶
Match-Objekt, das erfolgreiche
match- undsearch-Aufrufe zurückgeben.Matches sind generisch über den Typ der abgeglichenen Zeichenkette (
stroderbytes).Geändert in Version 3.9:
re.Matchunterstützt[], um eine Unicode-Fundstelle (str) oder eine bytes-Fundstelle anzugeben. Siehe Generic-Alias-Typ.
- Match.expand(template)¶
Gibt die Zeichenkette zurück, die entsteht, wenn in der Vorlagenzeichenkette template die Backslash-Ersetzung durchgeführt wird, wie es die Methode
sub()tut. Escapes wie\nwerden in die entsprechenden Zeichen umgewandelt, und numerische Rückwärtsverweise (\1,\2) sowie benannte Rückwärtsverweise (\g<1>,\g<name>) werden durch den Inhalt der entsprechenden Gruppe ersetzt. Der Rückwärtsverweis\g<0>wird durch die gesamte Fundstelle ersetzt.Geändert in Version 3.5: Gruppen ohne Fundstelle werden durch eine leere Zeichenkette ersetzt.
- Match.group([group1, ...])¶
Gibt eine oder mehrere Untergruppen der Fundstelle zurück. Bei einem einzigen Argument ist das Ergebnis eine einzelne Zeichenkette. Bei mehreren Argumenten ist es ein Tupel mit einem Element je Argument. Ohne Argumente ist group1 null (die gesamte Fundstelle wird zurückgegeben). Ist ein Argument groupN null, ist der entsprechende Rückgabewert die gesamte passende Zeichenkette. Ist es eine positive ganze Zahl, ist es die Zeichenkette, die auf die entsprechende geklammerte Gruppe passt. Ist eine Gruppennummer negativ oder größer als die Anzahl der im Muster festgelegten Gruppen, wird eine
IndexError-Ausnahme ausgelöst. Steht eine Gruppe in einem Teil des Musters, der nicht gepasst hat, ist das entsprechende ErgebnisNone. Steht eine Gruppe in einem Teil des Musters, der mehrfach gepasst hat, wird die letzte Fundstelle zurückgegeben.>>> m = re.search(r"\A(\w+) (\w+)", "Norwegian Blue, pining for the fjords") >>> m.group(0) # The entire match 'Norwegian Blue' >>> m.group(1) # The first parenthesized subgroup. 'Norwegian' >>> m.group(2) # The second parenthesized subgroup. 'Blue' >>> m.group(1, 2) # Multiple arguments give us a tuple. ('Norwegian', 'Blue')
Verwendet der reguläre Ausdruck die Syntax
(?P<name>...), können die groupN-Argumente auch Zeichenketten sein, die Gruppen über ihren Namen ansprechen. Wird eine als Argument übergebene Zeichenkette im Muster nicht als Gruppenname verwendet, wird eineIndexError-Ausnahme ausgelöst.Ein etwas verwickelteres Beispiel:
>>> m = re.search(r"(?P<adjective>\w+) (?P<animal>\w+)", "killer rabbit") >>> m.group('adjective') 'killer' >>> m.group('animal') 'rabbit'
Benannte Gruppen lassen sich auch über ihren Index ansprechen:
>>> m.group(1) 'killer' >>> m.group(2) 'rabbit'
Passt eine Gruppe mehrfach, ist nur die letzte Fundstelle zugänglich:
>>> m = re.search(r"(..)+", "a1b2c3") # Matches 3 times. >>> m.group(1) # Returns only the last match. 'c3'
- Match.__getitem__(g)¶
Das ist gleichbedeutend mit
m.group(g). Damit lässt sich einfacher auf eine einzelne Gruppe einer Fundstelle zugreifen:>>> m = re.search(r"(\w+) (\w+)", "Norwegian Blue, pining for the fjords") >>> m[0] # The entire match 'Norwegian Blue' >>> m[1] # The first parenthesized subgroup. 'Norwegian' >>> m[2] # The second parenthesized subgroup. 'Blue'
Benannte Gruppen werden ebenfalls unterstützt:
>>> m = re.search(r"(?P<adjective>\w+) (?P<animal>\w+)", "killer rabbit") >>> m['adjective'] 'killer' >>> m['animal'] 'rabbit'
Added in version 3.6.
- Match.groups(default=None)¶
Gibt ein Tupel mit allen Untergruppen der Fundstelle zurück, von 1 bis zur Anzahl der Gruppen im Muster. Das Argument default wird für Gruppen verwendet, die nicht an der Fundstelle beteiligt waren. Voreingestellt ist
None.Zum Beispiel:
>>> m = re.search(r"(\d+)\.(\d+)", "24.1632") >>> m.groups() ('24', '1632')
Machen wir das Dezimaltrennzeichen und alles danach optional, sind möglicherweise nicht alle Gruppen an der Fundstelle beteiligt. Diese Gruppen sind dann
None, sofern nicht das Argument default angegeben ist:>>> m = re.search(r"(\d+)\.?(\d+)?", "24") >>> m.groups() # Second group defaults to None. ('24', None) >>> m.groups('0') # Now, the second group defaults to '0'. ('24', '0')
- Match.groupdict(default=None)¶
Gibt ein Dictionary mit allen benannten Untergruppen der Fundstelle zurück, mit dem Namen der Untergruppe als Schlüssel. Das Argument default wird für Gruppen verwendet, die nicht an der Fundstelle beteiligt waren. Voreingestellt ist
None. Zum Beispiel:>>> m = re.search(r"(?P<adjective>\w+) (?P<animal>\w+)", "killer rabbit") >>> m.groupdict() {'adjective': 'killer', 'animal': 'rabbit'}
- Match.start([group])¶
- Match.end([group])¶
Gibt die Indizes von Anfang und Ende der Teilzeichenkette zurück, auf die group gepasst hat. Voreingestellt ist group null (also die gesamte gefundene Teilzeichenkette). Gibt
-1zurück, wenn group vorhanden ist, aber nicht zur Fundstelle beigetragen hat. Für ein Match-Objekt m und eine Gruppe g, die zur Fundstelle beigetragen hat, ist die von Gruppe g erfasste Teilzeichenkette (gleichbedeutend mitm.group(g))m.string[m.start(g):m.end(g)]
Beachte, dass
m.start(group)gleichm.end(group)ist, wenn group auf eine leere Zeichenkette gepasst hat. Nachm = re.search('b(c?)', 'cba')ist zum Beispielm.start(0)gleich 1,m.end(0)gleich 2,m.start(1)undm.end(1)sind beide 2, undm.start(2)löst eineIndexError-Ausnahme aus.Ein Beispiel, das remove_this aus E-Mail-Adressen entfernt:
>>> email = "tony@tiremove_thisger.net" >>> m = re.search("remove_this", email) >>> email[:m.start()] + email[m.end():] 'tony@tiger.net'
- Match.span([group])¶
Gibt für eine Fundstelle m das Zweiertupel
(m.start(group), m.end(group))zurück. Beachte: Hat group nicht zur Fundstelle beigetragen, ist das(-1, -1). Voreingestellt ist group null, also die gesamte Fundstelle.
- Match.pos¶
Der Wert von pos, der der Methode
search()odermatch()eines Regex-Objekts übergeben wurde. Das ist der Index in der Zeichenkette, an dem die RE-Maschine mit der Suche begonnen hat.
- Match.endpos¶
Der Wert von endpos, der der Methode
search()odermatch()eines Regex-Objekts übergeben wurde. Das ist der Index in der Zeichenkette, über den die RE-Maschine nicht hinausgeht.
- Match.lastindex¶
Der ganzzahlige Index der letzten erfassenden Gruppe mit Fundstelle oder
None, wenn überhaupt keine Gruppe gepasst hat. Die Ausdrücke(a)b,((a)(b))und((ab))haben zum Beispiellastindex == 1, wenn man sie auf die Zeichenkette'ab'anwendet, während der Ausdruck(a)(b)bei derselben Zeichenkettelastindex == 2hat.
- Match.lastgroup¶
Der Name der letzten erfassenden Gruppe mit Fundstelle oder
None, wenn die Gruppe keinen Namen hatte oder wenn überhaupt keine Gruppe gepasst hat.
- Match.re¶
Das Objekt des regulären Ausdrucks, dessen Methode
match()odersearch()diese Match-Instanz erzeugt hat.
Geändert in Version 3.7: Unterstützung für copy.copy() und copy.deepcopy() hinzugefügt. Match-Objekte gelten als atomar.
Beispiele für reguläre Ausdrücke¶
Auf ein Paar prüfen¶
In diesem Beispiel verwenden wir die folgende Hilfsfunktion, um Match-Objekte etwas gefälliger darzustellen:
def displaymatch(match):
if match is None:
return None
return '<Match: %r, groups=%r>' % (match.group(), match.groups())
Nehmen wir an, du schreibst ein Pokerprogramm, in dem das Blatt eines Spielers als Zeichenkette aus 5 Zeichen dargestellt wird, wobei jedes Zeichen für eine Karte steht: „a“ für Ass, „k“ für König, „q“ für Dame, „j“ für Bube, „t“ für 10 und „2“ bis „9“ für die Karte mit diesem Wert.
Um zu prüfen, ob eine gegebene Zeichenkette ein gültiges Blatt ist, ließe sich Folgendes tun:
>>> valid_hand_re = re.compile(r"^[a2-9tjqk]{5}$")
>>> displaymatch(valid_hand_re.search("akt5q")) # Valid.
"<Match: 'akt5q', groups=()>"
>>> displaymatch(valid_hand_re.search("akt5e")) # Invalid.
>>> displaymatch(valid_hand_re.search("akt")) # Invalid.
>>> displaymatch(valid_hand_re.search("727ak")) # Valid.
"<Match: '727ak', groups=()>"
Das letzte Blatt, "727ak", enthielt ein Paar, also zwei Karten desselben Werts. Um darauf mit einem regulären Ausdruck zu passen, ließen sich Rückwärtsverweise so verwenden:
>>> pair_re = re.compile(r".*(.).*\1")
>>> displaymatch(pair_re.prefixmatch("717ak")) # Pair of 7s.
"<Match: '717', groups=('7',)>"
>>> displaymatch(pair_re.prefixmatch("718ak")) # No pairs.
>>> displaymatch(pair_re.prefixmatch("354aa")) # Pair of aces.
"<Match: '354aa', groups=('a',)>"
Um herauszufinden, aus welcher Karte das Paar besteht, ließe sich die Methode group() des Match-Objekts so verwenden:
>>> pair_re = re.compile(r".*(.).*\1")
>>> pair_re.prefixmatch("717ak").group(1)
'7'
# Error because prefixmatch() returns None, which doesn't have a group() method:
>>> pair_re.prefixmatch("718ak").group(1)
Traceback (most recent call last):
File "<pyshell#23>", line 1, in <module>
pair_re.prefixmatch("718ak").group(1)
AttributeError: 'NoneType' object has no attribute 'group'
>>> pair_re.prefixmatch("354aa").group(1)
'a'
scanf() nachbilden¶
Python hat derzeit kein Gegenstück zu scanf(). Reguläre Ausdrücke sind im Allgemeinen mächtiger, aber auch wortreicher als die Formatzeichenketten von scanf(). Die Tabelle unten zeigt einige mehr oder weniger gleichwertige Zuordnungen zwischen den Formattokens von scanf() und regulären Ausdrücken.
|
Regulärer Ausdruck |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Um Dateinamen und Zahlen aus einer Zeichenkette wie dieser zu gewinnen:
/usr/sbin/sendmail - 0 errors, 4 warnings
würdest du ein scanf()-Format wie dieses verwenden:
%s - %d errors, %d warnings
Der entsprechende reguläre Ausdruck wäre:
(\S+) - (\d+) errors, (\d+) warnings
search() gegenüber prefixmatch()¶
Python bietet verschiedene Grundoperationen auf der Basis regulärer Ausdrücke:
re.prefixmatch()sucht eine Fundstelle nur am Anfang der Zeichenkettere.search()sucht eine Fundstelle irgendwo in der Zeichenkette (das tut Perl voreingestellt)re.fullmatch()prüft, ob die gesamte Zeichenkette passt
Zum Beispiel:
>>> re.prefixmatch("c", "abcdef") # No match
>>> re.search("c", "abcdef") # Match
<re.Match object; span=(2, 3), match='c'>
>>> re.fullmatch("p.*n", "python") # Match
<re.Match object; span=(0, 6), match='python'>
>>> re.fullmatch("r.*n", "python") # No match
Reguläre Ausdrücke, die mit '^' beginnen, lassen sich mit search() verwenden, um die Fundstelle auf den Anfang der Zeichenkette zu beschränken:
>>> re.prefixmatch("c", "abcdef") # No match
>>> re.search("^c", "abcdef") # No match
>>> re.search("^a", "abcdef") # Match
<re.Match object; span=(0, 1), match='a'>
Beachte allerdings, dass prefixmatch() im MULTILINE-Modus nur am Anfang der Zeichenkette passt, während search() mit einem regulären Ausdruck, der mit '^' beginnt, am Anfang jeder Zeile passt.
>>> re.prefixmatch("X", "A\nB\nX", re.MULTILINE) # No match
>>> re.search("^X", "A\nB\nX", re.MULTILINE) # Match
<re.Match object; span=(4, 5), match='X'>
prefixmatch() gegenüber match()¶
Warum wird von der Funktion und Methode match() zugunsten der längeren Schreibweise prefixmatch() abgeraten?
Viele andere Sprachen haben seit der Aufnahme regulärer Ausdrücke in Python Bibliotheken für Regexes bekommen. In den verbreitetsten davon steht der Begriff match in den APIs allerdings für das nicht verankerte Verhalten, das in Python search() bietet. Der schlichte Begriff match kann daher für jene unklar sein, die aus anderen Sprachen kommen und beim Lesen oder Schreiben von Code nicht wissen, dass die Python-API von der sonst üblichen Branchennorm abweicht.
Aus dem Zen of Python (python3 -m this): „Explicit is better than implicit“. Wer den Namen prefixmatch() liest, versteht die gemeinte Bedeutung wahrscheinlich sofort. Bei match() bleibt für alle, die diese alte Python-Falle nicht schon kennen, ein Rest Zweifel am gemeinten Verhalten.
Wir haben nicht vor, den älteren Namen match() zu entfernen, denn er wird seit über 30 Jahren in Code verwendet. Er ist soft deprecated: Code, der ältere Python-Versionen unterstützt, sollte weiterhin match() verwenden, neuer Code besser prefixmatch().
Added in version 3.15: prefixmatch()
Sanft abgekündigt <Soft deprecated> seit Version 3.15: match()
Ein Telefonbuch erstellen¶
split() teilt eine Zeichenkette an dem übergebenen Muster in eine Liste auf. Die Methode ist von unschätzbarem Wert, um Textdaten in Datenstrukturen zu verwandeln, die Python leicht lesen und ändern kann, wie das folgende Beispiel zeigt, das ein Telefonbuch erstellt.
Zuerst die Eingabe. Normalerweise käme sie aus einer Datei, hier verwenden wir die Syntax mit dreifachen Anführungszeichen
>>> text = """Ross McFluff: 834.345.1254 155 Elm Street
...
... Ronald Heathmore: 892.345.3428 436 Finley Avenue
... Frank Burger: 925.541.7625 662 South Dogwood Way
...
...
... Heather Albrecht: 548.326.4584 919 Park Place"""
Die Einträge sind durch einen oder mehrere Zeilenumbrüche getrennt. Nun verwandeln wir die Zeichenkette in eine Liste, in der jede nicht leere Zeile ihren eigenen Eintrag hat:
>>> entries = re.split("\n+", text)
>>> entries
['Ross McFluff: 834.345.1254 155 Elm Street',
'Ronald Heathmore: 892.345.3428 436 Finley Avenue',
'Frank Burger: 925.541.7625 662 South Dogwood Way',
'Heather Albrecht: 548.326.4584 919 Park Place']
Schließlich teilen wir jeden Eintrag in eine Liste mit Vorname, Nachname, Telefonnummer und Adresse auf. Wir verwenden den Parameter maxsplit von split(), weil die Adresse Leerzeichen enthält, also unser Trennmuster:
>>> [re.split(":? ", entry, maxsplit=3) for entry in entries]
[['Ross', 'McFluff', '834.345.1254', '155 Elm Street'],
['Ronald', 'Heathmore', '892.345.3428', '436 Finley Avenue'],
['Frank', 'Burger', '925.541.7625', '662 South Dogwood Way'],
['Heather', 'Albrecht', '548.326.4584', '919 Park Place']]
Das Muster :? passt auf den Doppelpunkt nach dem Nachnamen, sodass er nicht in der Ergebnisliste auftaucht. Mit einem maxsplit von 4 ließe sich die Hausnummer vom Straßennamen trennen:
>>> [re.split(":? ", entry, maxsplit=4) for entry in entries]
[['Ross', 'McFluff', '834.345.1254', '155', 'Elm Street'],
['Ronald', 'Heathmore', '892.345.3428', '436', 'Finley Avenue'],
['Frank', 'Burger', '925.541.7625', '662', 'South Dogwood Way'],
['Heather', 'Albrecht', '548.326.4584', '919', 'Park Place']]
Text verwursten¶
sub() ersetzt jedes Vorkommen eines Musters durch eine Zeichenkette oder das Ergebnis einer Funktion. Dieses Beispiel zeigt sub() mit einer Funktion, die Text „verwurstet“, also die Reihenfolge aller Zeichen in jedem Wort eines Satzes außer dem ersten und letzten Zeichen zufällig vertauscht:
>>> def repl(m):
... inner_word = list(m.group(2))
... random.shuffle(inner_word)
... return m.group(1) + "".join(inner_word) + m.group(3)
...
>>> text = "Professor Abdolmalek, please report your absences promptly."
>>> re.sub(r"(\w)(\w+)(\w)", repl, text)
'Poefsrosr Aealmlobdk, pslaee reorpt your abnseces plmrptoy.'
>>> re.sub(r"(\w)(\w+)(\w)", repl, text)
'Pofsroser Aodlambelk, plasee reoprt yuor asnebces potlmrpy.'
Alle Adverbien finden¶
findall() findet alle Vorkommen eines Musters und nicht nur das erste wie search(). Wollte etwa ein Autor alle Adverbien in einem Text finden, könnte er findall() so verwenden:
>>> text = "He was carefully disguised but captured quickly by police."
>>> re.findall(r"\w+ly\b", text)
['carefully', 'quickly']
Alle Adverbien und ihre Stellen finden¶
Will man über alle Fundstellen eines Musters mehr erfahren als den gefundenen Text, ist finditer() nützlich, denn es liefert Match-Objekte statt Zeichenketten. Um im vorigen Beispiel alle Adverbien und ihre Stellen in einem Text zu finden, würde ein Autor finditer() so verwenden:
>>> text = "He was carefully disguised but captured quickly by police."
>>> for m in re.finditer(r"\w+ly\b", text):
... print('%02d-%02d: %s' % (m.start(), m.end(), m.group(0)))
07-16: carefully
40-47: quickly
Raw-String-Schreibweise¶
Die Raw-String-Schreibweise (r"text") hält reguläre Ausdrücke bei Verstand. Ohne sie müsste jedem Backslash ('\') in einem regulären Ausdruck ein weiterer zur Maskierung vorangestellt werden. Die beiden folgenden Codezeilen sind zum Beispiel funktional gleich:
>>> re.search(r"\W(.)\1\W", " ff ")
<re.Match object; span=(0, 4), match=' ff '>
>>> re.search("\\W(.)\\1\\W", " ff ")
<re.Match object; span=(0, 4), match=' ff '>
Will man auf einen wörtlichen Backslash passen, muss er im regulären Ausdruck maskiert werden. In der Raw-String-Schreibweise heißt das r"\\". Ohne Raw-String-Schreibweise muss man "\\\\" verwenden. Die folgenden Codezeilen sind damit funktional gleich:
>>> re.search(r"\\", r"\\")
<re.Match object; span=(0, 1), match='\\'>
>>> re.search("\\\\", r"\\")
<re.Match object; span=(0, 1), match='\\'>
Einen Tokenizer schreiben¶
Ein Tokenizer oder Scanner untersucht eine Zeichenkette, um Gruppen von Zeichen in Kategorien einzuteilen. Das ist ein nützlicher erster Schritt beim Schreiben eines Compilers oder Interpreters.
Die Textkategorien werden mit regulären Ausdrücken angegeben. Die Technik besteht darin, sie zu einem einzigen übergeordneten regulären Ausdruck zu verbinden und über die aufeinanderfolgenden Fundstellen zu iterieren:
from typing import NamedTuple
import re
class Token(NamedTuple):
type: str
value: int | float | str
line: int
column: int
def tokenize(code):
keywords = {'IF', 'THEN', 'ENDIF', 'FOR', 'NEXT', 'GOSUB', 'RETURN'}
token_specification = [
('NUMBER', r'\d+(\.\d*)?'), # Integer or decimal number
('ASSIGN', r':='), # Assignment operator
('END', r';'), # Statement terminator
('ID', r'[A-Za-z]+'), # Identifiers
('OP', r'[+\-*/]'), # Arithmetic operators
('NEWLINE', r'\n'), # Line endings
('SKIP', r'[ \t]+'), # Skip over spaces and tabs
('MISMATCH', r'.'), # Any other character
]
tok_regex = '|'.join('(?P<%s>%s)' % pair for pair in token_specification)
line_num = 1
line_start = 0
for mo in re.finditer(tok_regex, code):
kind = mo.lastgroup
value = mo.group()
column = mo.start() - line_start
if kind == 'NUMBER':
value = float(value) if '.' in value else int(value)
elif kind == 'ID' and value in keywords:
kind = value
elif kind == 'NEWLINE':
line_start = mo.end()
line_num += 1
continue
elif kind == 'SKIP':
continue
elif kind == 'MISMATCH':
raise RuntimeError(f'{value!r} unexpected on line {line_num}')
yield Token(kind, value, line_num, column)
statements = '''
IF quantity THEN
total := total + price * quantity;
tax := price * 0.05;
ENDIF;
'''
for token in tokenize(statements):
print(token)
Der Tokenizer erzeugt die folgende Ausgabe:
Token(type='IF', value='IF', line=2, column=4)
Token(type='ID', value='quantity', line=2, column=7)
Token(type='THEN', value='THEN', line=2, column=16)
Token(type='ID', value='total', line=3, column=8)
Token(type='ASSIGN', value=':=', line=3, column=14)
Token(type='ID', value='total', line=3, column=17)
Token(type='OP', value='+', line=3, column=23)
Token(type='ID', value='price', line=3, column=25)
Token(type='OP', value='*', line=3, column=31)
Token(type='ID', value='quantity', line=3, column=33)
Token(type='END', value=';', line=3, column=41)
Token(type='ID', value='tax', line=4, column=8)
Token(type='ASSIGN', value=':=', line=4, column=12)
Token(type='ID', value='price', line=4, column=15)
Token(type='OP', value='*', line=4, column=21)
Token(type='NUMBER', value=0.05, line=4, column=23)
Token(type='END', value=';', line=4, column=27)
Token(type='ENDIF', value='ENDIF', line=5, column=4)
Token(type='END', value=';', line=5, column=9)
Friedl, Jeffrey. Mastering Regular Expressions. 3. Auflage, O’Reilly Media, 2009. Die dritte Auflage des Buches behandelt Python gar nicht mehr, die erste Auflage ging dagegen ausführlich darauf ein, wie man gute Muster für reguläre Ausdrücke schreibt.