RegEx-Lesson

Autor: Torsten Roeder
Lizenz: Creative Commons Attribution 4.0 International (CC BY 4.0)

FH Potsdam, 29.06.2021

  • 15 Min Einführung
  • 60 Min Übung
  • 15 Min Reflektion

Digitale Textarbeit

Alle von uns müssen regelmäßig mit Text arbeiten: Texte schreiben natürlich, aber oft auch Texte überarbeiten oder durchsuchen. Die Grundmechanismen von »Suchen und Ersetzen« reichen dabei oft nicht aus: Vielleicht suchen wir Abkürzungen in Texten, um diese zu vereinheitlichen, oder wir möchten unsere Datumsangaben auf ein bestimmtes Format umstellen. Oder wir möchten Adressangaben aus einem Text extrahieren. Das alles kann mühselige Handarbeit bedeuten. Aber es gibt auch andere Wege. Wir erlernen hier eine Technik, die in alltäglichen, konkreten Anwendungsfällen hilfreich ist.

Vorübung (in Breakouts)

Ein Beispiel: Wir möchten nach Kontaktdaten in einem Text suchen. Wir wissen, dass Kontaktinformationen nach bestimmten Mustern aufgebaut sind. Wenn wir dieses Muster beschreiben können, dann können wir auch danach suchen.

Aufgabe: Formal (frei, selbst gewählte Syntax) beschreiben, wie man

  1. eine E-Mail-Adresse
  2. eine WWW-Adresse
  3. eine Telefonnummer
  4. ein Datum
  5. eine Straße mit einer Hausnummer
  6. eine Postleitzahl mit einem Ort

erkennt. Dabei zwischen Zeichenarten unterscheiden, wie z.B Ziffern, Großbuchstaben, Kleinbuchstaben, Leerzeichen, bestimmte Satzzeichen.

Was braucht man für die Beschreibung des Suchmusters? Die »Trefferquote« muss nicht 100% akkurat sein, aber die meisten erwartbaren Fälle abdecken. Wie verhält es sich mit false positives/negatives (also: welche Fälle werden ggf. nicht erkannt, und welche werden fälschlich erkannt)?

Reguläre Ausdrücke

Eine große Hilfe stellen die sogenannten »regulären Ausdrücke« dar, oder englisch: »regular expressions«. Es handelt sich um eine Syntax für Suchbegriffe, die den Einsatz von Jokerzeichen erlaubt. Die Joker können nach bestimmten Regeln angepasst werden. Reguläre Ausdrücke sind allgemein formale Beschreibungen von Textmustern.

Reguläre Ausdrücke haben außerdem den großen Vorteil, dass sie in sehr vielen Umgebungen unterstützt werden. Beispielsweise LibreOffice, Oxygen Editor, Notepad++ und viele andere Programme bieten die Suche mit regulären Ausdrücken an (nur nicht Microsoft Word). Die meisten Programmiersprachen unterstützen ebenfalls reguläre Ausdrücke. Es handelt sich um eine relativ breit unterstützte Textverarbeitungsmethode, die allerdings mehr im programmiernahen Bereich beheimatet ist.

Übungen

Fiddle: https://regexr.com/ (alternativ: https://regex101.com/)

RegEx-Referenz: https://www.regular-expressions.info

Beispieltext: http://www.zeno.org/nid/20004412516

Level 1: Zeichen und Joker

  • Zeichen/Zeichenketten durch andere ersetzen:
    • z.B. Kaiser durch Köhler
  • der Punkt . fungiert als Jokerzeichen:
    • z.B. sch.n findet schön, schon und (Men)schen
    • z.B. Kaiser. findet Kaisers, Kaiser,, Kaiser und (theoretisch) Kaiserö
  • nach Punkt suchen mit \ als »escape«:
    • z.B. Kleider\. findet genau Kleider.
  • der Joker allein bringt relativ wenig, weil er quasi alles enthalten kann

Level 2: Klassen

  • Zeichenklassen: Zahlen und Buchstaben anwenden
    • einfache Klassen: [a-z], [0-9]
    • negierende Klassen: [^aeiou]
    • Klammerzeichen ggf. mit \ escapen
  • Shorthands: Kurzschreibweisen für Klassen
    • z.B. \s (Spaces), \w (Wortzeichen), \d (Ziffern)
    • was drin ist, kann man nachschauen (siehe Referenz oben)
    • \w (und [a-z]) enthalten keine Umlaute!
  • z.B. finde eine Seitenzahl im Text:
    • [0-9][0-9][0-9]
    • mit Shorthands: \d\d\d
    • mit den umgebenden Klammern: \[\d\d\d\]

Level 3: Quantifizierer

  • Mehrfach-Suchzeichen
    • beziehen sich immer auf das vorhergehende Zeichen
    • sind »greedy«: finden immer so viel wie möglich
    • +: 1 oder mehr
    • *: 0 oder mehr
    • ?: 0 oder 1 = »optional«
    • z.B. K[a-zäöüß]+ findet alle Wörter mit K
  • oft mit Joker kombiniert
    • .* findet den gesamten Text
  • lazy: +? und *?
    • z.B. »(.*)« vs. »(.*?)«
  • range: {n,m} findet zwischen n und m Zeichen
    • z.B. K[a-zäöüß]{6}
    • z.B. K[a-zäöüß]{4,5}r
  • ggf. escapen mit \

Level 4: Gruppen

  • Klammerzeichen () umschließen eine Gruppe
  • mehrere Möglichkeiten mit | abgrenzen
    • z.B. Beamt(en|e) findet Beamte und Beamten (Priorität von links nach rechts)
    • kürzer: Beamte(n|)
    • z.B. (Be)?[aA]mt(en|e|) findet auch Amt und Amte
  • Klammerzeichen ggf. mit \ escapen
  • beim Ersetzen kann jede Gruppe mit $1 adressiert werden
    • z.B.: \[(\d\d\d)\] durch [Seite $1]
    • z.B.: Quelle: (.*?), (.*?): durch Quelle: $2 $1:
  • ergo: mit Gruppen kann man verschiedene Fälle ausdifferenzieren

Endgegner: Zeilenumbrüche

  • Zeilenumbrüche erkennen
    • \r: carriage return (Mac vor OS X)
    • \n: new line (Unix, Mac ab OS X)
    • \r\n: carriage return, new line (Windows)
  • Begriffe von alten Printgeräten, ähnlich Schreibmaschinen
  • als Klasse: [\r\n]+
  • oder als Gruppe: (\r|\n|\r\n) oder auch (\r\n?|\n)

Aufgabe

Beispieltext (PDF):
https://meinclio.clio-online.de/open/pdf/conferencereport/fdkn-123139/

Ziel:
ein gut lesbares Textdokument

Was könnte man tun?

  1. Kopf/Fußzeilen rauswerfen
  2. Personennamen klein schreiben
  3. Absätze und Überschriften durch eine Leerzeile abtrennen
  4. Worttrennungen aufheben
  5. Fußnotenanker in Klammern setzen
  6. Fußnotentext ans Ende des Textes verschieben