Empfohlene Unterrichtsinhalte als Vorbereitung für dieses Thema: 02-01 (Strings), 05-03 (Module), 09-01 (Regular Expressions schreiben), 09-02 (Regular Expressions in Python verarbeiten)

Einführung in die computerlinguistische Programmierung mit Python

09-03: Regular Expressions und Gruppen 🤹‍♀️

Wenn ein regulärer Ausdruck ein komplexes Muster beschreibt, ist es oft hilfreich, die Teil-Matches aus dem analysierten String zu extrahieren und z.B. in Variablen zu speichern. Um das zu erreichen, arbeiten wir mit Gruppen, die bei regulären Ausdrücken durch runde Klammern (...) markiert werden.

Die Funktion group() kann auf RegEx-Matches angewendet werden und ermöglicht uns, auf die verschiedenen Gruppen des Matches zuzugreifen. Im folgenden Beispiel besteht der reguläre Ausdruck aus zwei Gruppen und wird auf den Beispielstring gematcht. Die Gruppe mit dem Index 0 entspricht dem gesamten Match. Danach folgen in aufsteigender Reihenfolge die Teil-Matches für jede Gruppe, gezählt von links vom Start des Strings. Wie viele groups wir verwenden können, hängt davon ab, wie viele Gruppen im regulären Ausdruck enthalten sind.

Falls Gruppen ineinander verschachtelt sind, zählt für die Nummerierung die Reihenfolge der öffnenden Klammern. Hier das gleiche Beispiel von oben noch einmal, nur mit einer zusätzlichen Gruppe im regulären Ausdruck:

Die Gruppen sind am nützlichsten, wenn wir verschiedene Informationen aus einem String extrahieren und sie in einer strukturierten Form abspeichern wollen. Im folgenden Beispiel erhalten wir einen String mit einer Deklinationstabelle für ein lateinisches Substantiv. Ziel des Codes ist es, ein Dictionary zu erstellen, in dem die Informationen aus dem String abgespeichert werden und dann jederzeit wieder abgerufen werden können.

Gruppen und Teilmatches im Brief von Heinrich Heine

Im letzten Thema, 09-02, haben wir einen Brief von Heinrich Heine mit re.split() in seine einzelnen Sätze zerlegt, aber dabei gingen die Satzzeichen verloren.

Hier ein Vorschlag, wie es stattdessen gehen könnte. Diesmal definieren wir den regulären Ausdruck so, dass jeder Satz komplett von einer eigenen Gruppe abgedeckt wird. re.split() verhält sich dann anders, weil wir explizit definiert haben, dass das jeweilige Satzzeichen zum Satz dazugehört und deshalb beim Zerteilen nicht verloren gehen soll. re.split() berücksichtigt alle Elemente, die Teil einer Gruppe sind, und verhindert, dass Elemente innerhalb von Gruppen verloren gehen.

re.findall() im Brief von Heinrich Heine

Schließlich gibt es noch die Möglichkeit, mit re.findall() alle Teilstrings, die zum Muster passen, zu finden. Da unser regulärer Ausdruck jetzt immer genau einen Satz abdeckt, können wir das leicht umsetzen. Die RegEx bleibt so, wie wir sie eben schon definiert haben; nur die Verarbeitung des Strings läuft jetzt etwas anders.

Hier gilt es zu beachten, dass re.findall() uns nur Strings zurückgibt, keine zusätzlichen Informationen wie z.B. bei re.search(). Das ist aber kein Problem, solange uns sowieso nur der Stringinhalt der Teilmatches interessiert.

Zusammenfassung

Weitere Themen dieser Woche: