RegEx – sogenannte Reguläre Ausdrücke (englisch: Regular Expressions) sind ein mächtiges Werkzeug zum Durchsuchen, Überprüfen und Ersetzen von Text. Die meisten Programmiersprachen bieten Unterstützung für RexEx an, aber auch viele Texteditoren können beim Suchen und Ersetzen mit RegEx umgehen.
Idee
In der Syntax von RegEx lassen sich Muster definieren (engl. Pattern). Der Text wird dann nach diesen Mustern durchsucht. Die Muster geben an, welche Zeichen in welcher Reihenfolge und wie oft im Text vorkommen.
Man kann somit Text…
- überprüfen
- Kommt das Muster vor?
- Entspricht der Text dem Muster?
- suchen & extrahieren
- Wo finden wir das Muster?
- Was entspricht dem Muster?
- suchen & ersetzen
- Wo finden wir das Muster?
- Mit was ersetzen wir es?
Wir schauen uns als Beispiel die E-Mail-Regeln des vorherigen Kapitels an:
Beispiel E-Mail
Die Regeln lauten:
- mindestens ein Buchstabe oder eine Ziffer
- dann ein @
- dann wieder mindestens ein Buchstabe oder eine Ziffer
- dann ein Punkt
- dann wieder mindestens ein Buchstabe oder eine Ziffer
Das «mindestens ein Buchstabe oder eine Ziffer» können wir in der RegEx-Syntax wie folgt schreiben:
[a-z0-9]+
Die eckige Klammer gibt eine Menge von Zeichen an. Hier alle Kleinbuchstaben a-z
und alle Ziffern 0-9
. Mit dem +
sagen wir, dass so ein Zeichen mindestens 1x vorkommt, aber auch öfter vorkommen kann.
Wir können dieses «mindestens ein Zeichen» 3x verwenden. Dazwischen steht ein @ und ein Punkt. Den Punkt müssen wir «escapen», weil der in der RegEx-Syntax eine spezielle Bedeutung hat und wir ja das Zeichen «Punkt» meinen.
Daraus erhalten wir die folgende Syntax:
[a-z0-9]+@[a-z0-9]+\.[a-z0-9]+
Aufgabe: E-Mail
Teste die oben beschriebene RegEx online aus:
- öffne die Webseite https://extendsclass.com/regex-tester.html#python
- Stelle links unter RegEx Engine auf Python um
- Füge die obenstehende RegEx ins Feld Regular expression to test ein und schau dir das Diagramm unter Explanation an.
- Gib im Feld String to test einige E-Mail-Adressen ein und überprüfe jeweils
- wie viele Treffer es gibt
- und wo diese sind
in Python
Python bietet RegEx-Support im package re
. Aus diesem müssen wir alles was wir verwenden wollen importieren.
Wir verwenden zwei Unterprogramme dieses packages:
fullmatch
- entspricht der ganze geprüfte Text dem Muster
findall
- finde alle Vorkommen des Musters
Die Unterprogramme nehmen zwei Argumente entgegen – Das Pattern und den zu prüfenden Text:
- Pattern
- ein raw-String, gekennzeichnet mit
r
davor - jedes Zeichen wir sozusagen «roh» verwendet, z.B. ist
\n
dann kein newline, sondern einfach ein Backslash und einn
- Text
- normaler String
fullmatch
liefern ein match
-Objekt zurück (wie auch match
und search
). Gibt es keinen Treffer, so ist der Rückgabewert None
.
findall
liefert eine Liste von Strings zurück die dem Muster entsprechen.
from re import fullmatch
pattern = r"[a-z0-9]+@[a-z0-9]+\.[a-z0-9]+"
email = "ef2021@mygymer.ch"
m = fullmatch(pattern, email)
print(m)
if m:
print(email, "ist eine korrekte E-Mail-Adresse")
else:
print(email, "ist keine korrekte E-Mail-Adresse")
Aufgabe: E-Mail-Checker
Programmiere einen zweiten E-Mail-Checker:
- Verwende dazu die Vorlage aus dem letzten Kapitel
- Überprüfe jetzt aber die Eingabe mit RegEx
Python bietet natürlich viel mehr was RegEx angeht:
👉 https://docs.python.org/3/library/re.html
Zusatzaufgabe: E-Mail-Finder
Programmiere mit findall
ein Programm das aus einem grösseren Text alle E-Mail-Adresse extrahiert.
Möglicher Text zum testen:
text = """
Beispiele für seriöse Mail-Adressen: max@mustermann.de, maxmustermann@posteo.org, m.mustermann@posteo.de
Beispiele für schlechte Mail-Adressen: schnuffelmaus84@yahoo.de, mad.jonny@freemail.de, max_12@gmail.com
"""
Kannst du dein Muster verbessern?
Syntax
zugelassene Zeichen
Aus welchen Zeichen soll das Muster bestehen?
- genau
- dieses Zeichen schreiben, z.B.
@
oder\.
- Menge
- eines dieser Zeichen, z.B.
[aX7]
- ein Zeichen aus einem Bereich
[a-q]
- Spezial
\w
– ein Buchstabe (word)\s
– ein Leerzeichen (space)\d
– eine Ziffer (digit)- …
Wiederholungen
Wie oft soll das Zeichen vorkommen? Muss es? Darf es?
{n}
- n Mal
{a,b}
- mindestens a Mal, höchstens b Mal
*
- beliebig oft oder auch gar nie
+
- mindestens 1x, aber auch beliebig oft
?
- einmal oder gar nicht
Wir könnten also die Top-Level-Domain in der E-Mail-Adresse einschränken:
[a-z0-9]+@[a-z0-9]+\.[a-z0-9]{2,3}
Gruppen
Treffer können mit runden Klammern in Gruppen unterteilt und weiterverarbeitet werden. Z.B. könnten wir ein Textdokument nach E-Mail-Adressen durchsuchen und dabei die Domänen der Adressen vergleichen:
[a-z0-9]+@([a-z0-9]+\.[a-z0-9]{2,3})
Wenn wir Gruppen mit findall
verwenden, dann erhalten wir von jedem Treffer nur die gewünschte(n) Gruppe(n).
Zusatzaufgabe: Gruppen
Erweitere die Extrahier-Aufgabe und liste nun nur die Domänen der E-Mail-Adressen auf
Ersetzen
Mit Hilfe der Gruppierungsfunktion, lassen sich auch komplexe Such-und-Ersetz-Aktionen durchführen.
Zusatzaufgabe: Schwärzen
Gehe den Text durch und ersetze in jeder E-Mail-Adresse den Text vor dem @ (also der Benutzername) durch xy
.
Tipp: re.sub()
– https://docs.python.org/3/library/re.html#re.sub