Python - Regular Expressions (Deutsch)
Hallo da, zukünftige Python-Zauberer! Heute werden wir auf eine aufregende Reise in die Welt der regulären Ausdrücke (regex) in Python aufbrechen. Keine Sorge, wenn du noch nie von regex gehört hast – am Ende dieses Tutorials wirst du diese mächtige Werkzeug wie ein Profi führen!
Was sind Regular Expressions?
Bevor wir einsteigen, lassen uns verstehen, was reguläre Ausdrücke sind. Stell dir vor, du bist ein Detektiv, der versucht, ein bestimmtes Muster in einem Meer aus Text zu finden. Reguläre Ausdrücke sind wie dein Lupen, der dir hilft, nach Zeichenketten basierend auf Mustern zu suchen und zu manipulieren. Cool, nicht wahr?
Raw Strings
In Python verwenden wir bei der Arbeit mit regex oft Raw Strings. Diese sind mit einem 'r' prefixiert und behandeln Backslashes als literale Zeichen. Dies ist besonders nützlich in regex, da Backslashes häufig vorkommen.
# Normale Zeichenkette
print("Hallo\nWelt")
# Raw String
print(r"Hallo\nWelt")
Im ersten Fall wirst du "Hallo" und "Welt" in separaten Zeilen sehen. Im zweiten Fall wirst du "Hallo\nWelt" so wie es ist sehen. Dies wird entscheidend, wenn du mit regex-Mustern arbeitest.
Metacharaktere
Metacharaktere sind die Bausteine von regex. Sie haben spezielle Bedeutungen und helfen uns, Muster zu definieren. Lass uns einige gängige anschauen:
Metacharakter | Bedeutung |
---|---|
. | Stimmt mit jedem Zeichen außer Zeilenumbruch überein |
^ | Stimmt mit dem Anfang einer Zeichenkette überein |
$ | Stimmt mit dem Ende einer Zeichenkette überein |
* | Stimmt mit 0 oder mehr Wiederholungen überein |
+ | Stimmt mit 1 oder mehr Wiederholungen überein |
? | Stimmt mit 0 oder 1 Wiederholung überein |
{} | Stimmt mit einer explizit angegebenen Anzahl von Wiederholungen überein |
[] | Gibt eine Menge von Zeichen zum Stimmen an |
\ | Maskiert Sonderzeichen |
Die re.match() Funktion
Die re.match()
-Funktion versucht, ein Muster am Anfang einer Zeichenkette zu stimmen. Wenn sie ein Übereinstimmendes findet, gibt sie ein Übereinstimmungsobjekt zurück; andernfalls gibt sie None zurück.
import re
ergebnis = re.match(r"Hallo", "Hallo, Welt!")
if ergebnis:
print("Treffer gefunden:", ergebnis.group())
else:
print("Kein Treffer")
Dies wird "Treffer gefunden: Hallo" ausgeben. Die group()
-Methode gibt den übereinstimmenden Teilstring zurück.
Die re.search() Funktion
Während re.match()
am Anfang einer Zeichenkette nach einem Treffer sucht, durchsucht re.search()
die gesamte Zeichenkette nach einem Treffer.
import re
ergebnis = re.search(r"Welt", "Hallo, Welt!")
if ergebnis:
print("Treffer gefunden:", ergebnis.group())
else:
print("Kein Treffer")
Dies wird "Treffer gefunden: Welt" ausgeben.
Vergleich von match() und search()
Der Hauptunterschied zwischen match()
und search()
ist, dass match()
nur am Anfang der Zeichenkette nach einem Treffer sucht, während search()
überall in der Zeichenkette nach einem Treffer sucht.
Die re.findall() Funktion
Die re.findall()
-Funktion gibt alle nicht überlappenden Treffer eines Musters in einer Zeichenkette als Liste zurück.
import re
text = "Der Regen in Spanien fällt hauptsächlich in die Ebene"
ergebnis = re.findall(r"ain", text)
print(ergebnis)
Dies wird ['ain', 'ain', 'ain']
ausgeben.
Die re.sub() Funktion
Die re.sub()
-Funktion ersetzt alle Vorkommen eines Musters in einer Zeichenkette durch eine Ersatzzeichenkette.
import re
text = "Der Regen in Spanien"
ergebnis = re.sub(r"a", "o", text)
print(ergebnis)
Dies wird "Der Roegen in Spoin" ausgeben.
Die re.compile() Funktion
Die re.compile()
-Funktion erstellt ein regex-Objekt zur Wiederverwendung, was effizienter sein kann, wenn du das gleiche Muster mehrmals verwendest.
import re
muster = re.compile(r"\d+")
ergebnis1 = muster.findall("Es gibt 123 Äpfel und 456 Orangen")
ergebnis2 = muster.findall("Ich habe 789 Bananen")
print(ergebnis1)
print(ergebnis2)
Dies wird ['123', '456']
und ['789']
ausgeben.
Die re.finditer() Funktion
Die re.finditer()
-Funktion gibt einen Iterator zurück, der Übereinstimmungsobjekte für alle nicht überlappenden Treffer eines Musters in einer Zeichenkette liefert.
import re
text = "Der Regen in Spanien"
for treffer in re.finditer(r"ain", text):
print(f"Gefunden '{treffer.group()}' an Position {treffer.start()}-{treffer.end()}")
Dies wird ausgeben:
Gefunden 'ain' an Position 5-8
Gefunden 'ain' an Position 17-20
Anwendungsfälle von Python Regex
Reguläre Ausdrücke haben zahlreiche praktische Anwendungen. Lass uns einen gängigen Anwendungsfall anschauen:
Finden von Wörtern, die mit Vokalen beginnen
import re
text = "Ein Apfel am Tag hält den Arzt fern"
vokal_wörter = re.findall(r'\b[aeiouAEIOU]\w+', text)
print(vokal_wörter)
Dies wird ['Ein', 'Apfel', 'a', 'fern']
ausgeben.
Regular Expression Modifikatoren: Optionsschalter
Pythons re-Modul bietet mehrere Optionsschalter an, die beeinflussen, wie Muster interpretiert werden:
Schalter | Beschreibung |
---|---|
re.IGNORECASE (re.I) | Führt eine Groß- und Kleinschreibung ignorierende Übereinstimmung durch |
re.MULTILINE (re.M) | Macht ^ am Anfang jeder Zeile und $ am Ende jeder Zeile übereinstimmen |
re.DOTALL (re.S) | Macht . mit jedem Zeichen, einschließlich Zeilenumbruch, übereinstimmen |
re.VERBOSE (re.X) | Ermöglicht es dir, lesbarere regex-Muster zu schreiben |
Regular Expression Patterns
Lass uns einige fortgeschrittene Muster erkunden:
Zeichenklassen
Zeichenklassen ermöglichen es dir, eine Menge von Zeichen zum Stimmen an zu geben:
import re
text = "Der schnelle braune Fuchs springt über den faulen Hund"
ergebnis = re.findall(r"[aeiou]", text)
print(ergebnis)
Dies wird alle Vokale im Text ausgeben.
Spezielle Zeichenklassen
Python regex unterstützt spezielle Zeichenklassen:
Klasse | Beschreibung |
---|---|
\d | Stimmt mit jeder dezimalen Ziffer überein |
\D | Stimmt mit jedem nichtnumerischen Zeichen überein |
\s | Stimmt mit jedem Leerzeichenzeichen überein |
\S | Stimmt mit jedem nichtleeren Zeichen überein |
\w | Stimmt mit jedem alphanumerischen Zeichen überein |
\W | Stimmt mit jedem nichtalphanumerischen Zeichen überein |
Wiederholungsfälle
Wir können angeben, wie oft ein Muster auftreten soll:
import re
text = "Ich habe 111 Äpfel und 22 Orangen"
ergebnis = re.findall(r"\d{2,3}", text)
print(ergebnis)
Dies wird ['111', '22']
ausgeben, stimmt mit Zahlen mit 2 oder 3 Ziffern überein.
Nongreedy-Wiederholung
Standardmäßig ist die Wiederholung gierig, was bedeutet, dass sie so viel wie möglich übereinstimmt. Das Hinzufügen eines ? nach der Wiederholung macht sie non-greedy:
import re
text = "<h1>Titel</h1><p>Paragraph</p>"
gierig = re.findall(r"<.*>", text)
non_gierig = re.findall(r"<.*?>", text)
print("Gierig:", gierig)
print("Non-gierig:", non_gierig)
Dies wird den Unterschied zwischen gieriger und non-gieriger Übereinstimmung zeigen.
Gruppierung mit Klammern
Klammern ermöglichen es dir, Teile des regex zu gruppieren:
import re
text = "John Smith ([email protected])"
ergebnis = re.search(r"(\w+) (\w+) \((\w+@\w+\.\w+)\)", text)
if ergebnis:
print(f"Voller Name: {ergebnis.group(1)} {ergebnis.group(2)}")
print(f"Email: {ergebnis.group(3)}")
Dies extrahiert den Namen und die E-Mail aus dem Text.
Rückverweise
Rückverweise ermöglichen es dir, auf zuvor übereinstimmende Gruppen zu verweisen:
import re
text = "<h1>Titel</h1><p>Paragraph</p>"
ergebnis = re.findall(r"<(\w+)>.*?</\1>", text)
print(ergebnis)
Dies stimmt mit öffnenden und schließenden HTML-Tags überein.
Alternativen
Das | Zeichen ermöglicht es dir, Alternativen anzugeben:
import re
text = "Die Farbe des Himmels ist blau oder grau"
ergebnis = re.search(r"blau|grau", text)
if ergebnis:
print(f"Gefundene Farbe: {ergebnis.group()}")
Dies stimmt entweder mit "blau" oder "grau" überein.
Anker
Anker geben Positionen im Text an:
import re
text = "Python ist großartig"
start = re.match(r"^Python", text)
end = re.search(r"grossartig$", text)
print(f"Beginnt mit Python: {bool(start)}")
print(f"Endet mit grossartig: {bool(end)}")
Dies überprüft, ob der Text mit "Python" beginnt und mit "großartig" endet.
Spezielle Syntax mit Klammern
Klammern können für mehr als nur Gruppierung verwendet werden:
- (?:...) erstellt eine nicht erfasende Gruppe
- (?P
...) erstellt eine benannte Gruppe - (?=...) erstellt einen positiven Ausblick
- (?!...) erstellt einen negativen Ausblick
import re
text = "Python Version 3.9.5"
ergebnis = re.search(r"Python (?:Version )?(?P<version>\d+\.\d+\.\d+)", text)
if ergebnis:
print(f"Version: {ergebnis.group('version')}")
Dies extrahiert die Versionsnummer, obwohl "Version" im Text vorhanden sein mag oder nicht.
Und da haben wir es, Freunde! Wir haben durch die Welt der Python regex gereist, von den Grundlagen bis zu einige ziemlich fortgeschrittene Konzepte. Bedenke, wie jedes mächtige Werkzeug, nimmt es Praxis, um regex zu meistern. Also lass dich nicht entmutigen, wenn es am Anfang überwältigend erscheint. Führe weiterhin Experimente durch, und bald wirst du wie ein Profi-Detektiv Muster finden! Glückliches Coden!
Credits: Image by storyset