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 Reguläre Ausdrücke an, aber auch viele Texteditoren können beim Suchen und Ersetzen mit Regulären Ausdrücke umgehen.
Idee
In der Syntax von Reguläre Ausdrücken 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]+Das können wir ein wenig optimieren:
- im ersten Block lassen wir noch den
.Punkt und den_Unterstrich zu, weil die in E-Mail-Adressen erlaubt sind - den mittleren Block lassen wir so stehen
- im letzten Block beschränken wir die Top-Level-Domain auf 2 bis 3 Zeichen, ohne Ziffern
[a-z0-9]+@[a-z0-9]+\.[a-z]{2,3}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
rdavor - jedes Zeichen wir sozusagen «roh» verwendet, z.B. ist
\ndann kein newline, sondern einfach ein Backslash und einn - Text
- normaler String
Die beiden Unterprogramme liefern nstürlich Werte zurück:
fullmatch- liefern ein
match-Objekt zurück (wie auchmatchundsearch). Gibt es keinen Treffer, so ist der RückgabewertNone. 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 = "efin@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")2
3
4
5
6
7
8
9
10
11
12
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
Lösung: E-Mail-Checker (nicht angemeldet)
Diese Lösung ist nur für angemeldete Benutzer zugänglich – wenn die LK die Lösung freigegeben hat. Bitte melde dich an, um die Lösung einsehen zu können.Python bietet natürlich viel mehr was RegEx angeht:
👉 https://docs.python.org/3/library/re.html
Aufgabe: 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
"""2
3
4
Kannst du dein Muster verbessern?
Lösung: E-Mail-Finder (nicht angemeldet)
Diese Lösung ist nur für angemeldete Benutzer zugänglich – wenn die LK die Lösung freigegeben hat. Bitte melde dich an, um die Lösung einsehen zu können.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).
Aufgabe: Gruppen
Erweitere die Extrahier-Aufgabe und liste nun nur die Domänen der E-Mail-Adressen auf
Lösung: Gruppen (nicht angemeldet)
Diese Lösung ist nur für angemeldete Benutzer zugänglich – wenn die LK die Lösung freigegeben hat. Bitte melde dich an, um die Lösung einsehen zu können.Ersetzen
Mit Hilfe der Gruppierungsfunktion, lassen sich auch komplexe Such-und-Ersetz-Aktionen durchführen.
Aufgabe: 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