Reguläre Ausdrücke (englisch regular expressions, kurz Regex) beschreiben Textmuster: "eine Zahl mit fünf Ziffern", "eine E-Mail-Adresse", "ein Datum wie 24.12.2025". Mit dem Modul re suchst, prüfst und ersetzt du Text nach solchen Mustern.
Das Prinzip
import re
text = "Meine Nummer ist 12345, deine 67890."
print(re.search(r"\d+", text)) # erster Treffer
print(re.findall(r"\d+", text)) # alle Treffer als Liste
print(re.sub(r"\d", "#", text)) # ersetzen<re.Match object; span=(17, 22), match='12345'> ['12345', '67890'] Meine Nummer ist #####, deine #####.
Muster schreibt man als Raw-String r"...", damit Rückwärtsschrägstriche unverändert ankommen.
Bausteine
| Muster | Bedeutung |
|---|---|
. | beliebiges Zeichen (außer Zeilenumbruch) |
\d / \D | Ziffer / Nicht-Ziffer |
\w / \W | Wortzeichen (Buchstabe, Ziffer, _) / alles andere |
\s / \S | Leerraum / kein Leerraum |
^ / $ | Anfang / Ende des Textes |
\b | Wortgrenze |
[abc] | eines der Zeichen a, b oder c |
[a-z] | ein Kleinbuchstabe |
[^0-9] | alles außer Ziffern |
a|b | a oder b |
( ) | Gruppe |
Wiederholungen (Quantoren)
| Muster | Bedeutung |
|---|---|
x* | null oder mehr |
x+ | eins oder mehr |
x? | null oder eins |
x{3} | genau drei |
x{2,4} | zwei bis vier |
import re
print(re.findall(r"\d{4}", "Jahr 2024 und 1999"))
print(re.findall(r"colou?r", "color colour colr"))
print(re.fullmatch(r"[A-Z]{2}\d{3}", "AB123") is not None)
print(re.fullmatch(r"[A-Z]{2}\d{3}", "AB12") is not None)['2024', '1999'] ['color', 'colour'] True False
Gruppen
Mit Klammern holst du Teile eines Treffers heraus, auf Wunsch mit Namen:
import re
m = re.search(r"(\d{2})\.(\d{2})\.(\d{4})", "Geburtstag: 24.12.1999")
print(m.group(0))
print(m.groups())
m2 = re.search(r"(?P<tag>\d{2})\.(?P<monat>\d{2})", "am 05.11.")
print(m2.group("tag"), m2.group("monat"))24.12.1999
('24', '12', '1999')
05 11Funktionen des Moduls re
| Funktion | Wirkung |
|---|---|
re.search(muster, text) | erster Treffer irgendwo im Text (oder None) |
re.match(muster, text) | Treffer nur am Textanfang |
re.fullmatch(muster, text) | der ganze Text muss passen |
re.findall(muster, text) | Liste aller Treffer |
re.finditer(muster, text) | Iterator über Treffer-Objekte |
re.sub(muster, ersatz, text) | ersetzen |
re.split(muster, text) | an Treffern aufteilen |
re.compile(muster) | Muster vorübersetzen (schneller bei Wiederholung) |
import re
print(re.split(r"[,;]\s*", "a, b;c, d"))
print(re.sub(r"(\w+)@(\w+)\.de", r"\1 bei \2", "mia@beispiel.de"))
muster = re.compile(r"\b[A-Z][a-z]+\b")
print(muster.findall("Mia und Tom gehen nach Köln"))['a', 'b', 'c', 'd'] mia bei beispiel ['Mia', 'Tom']
Gierig oder sparsam
Quantoren sind standardmäßig gierig: Sie greifen so viel wie möglich. Ein angehängtes ? macht sie sparsam:
import re
html = "<b>fett</b> und <i>kursiv</i>"
print(re.findall(r"<.+>", html))
print(re.findall(r"<.+?>", html))['<b>fett</b> und <i>kursiv</i>'] ['<b>', '</b>', '<i>', '</i>']
Optionen
Mit Flags änderst du das Verhalten, etwa re.IGNORECASE (Groß/Klein egal) oder re.MULTILINE (^ und $ pro Zeile):
import re
print(re.findall(r"python", "Python python PYTHON", re.IGNORECASE))
print(re.findall(r"^\w+", "eins\nzwei", re.MULTILINE))['Python', 'python', 'PYTHON'] ['eins', 'zwei']
Merke
- Muster als Raw-String
r"..."schreiben search,match,fullmatch,findall,sub,split\d,\w,\s,.,[...], Quantoren* + ? {n}- Klammern bilden Gruppen (
m.group(1),(?P<name>...)) ?nach einem Quantor macht ihn sparsam; Flags wiere.IGNORECASE
Aufgabe
Schreibe ein Muster, das deutsche Postleitzahlen (fünf Ziffern) aus einem Text zieht, und prüfe, ob ein Text eine gültige Zeit wie 07:45 ist.