# RegEx-Lesson
Autor: Torsten Roeder
Lizenz: [Creative Commons Attribution 4.0 International (CC BY 4.0)](https://creativecommons.org/licenses/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