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]+
1

Die eckige Klammer gibt eine Menge von Zeichen an. Hier alle Kleinbuchstaben a-z und alle Ziffern 1-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]+
1

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 ein n
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")
    
1
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

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 
"""
1
2
3
4

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 wie er in einem Wort vorkommen kann
\s – ein Leerzeichen
\d – eine Ziffer

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}
1

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})
1

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