Informatik

Reguläre Ausdrücke verstehen und anwenden

Reguläre Ausdrücke verstehen und anwenden
Reguläre Ausdrücke verstehen und anwenden
Für Quiz, Lückentext, Lernkarten und Fortschritt ist JavaScript nötig. Alle Inhalte und Lösungen bleiben direkt lesbar.

Ein regulärer Ausdruck, kurz Regex, beschreibt ein Muster für Zeichenketten. Damit kannst du Text durchsuchen, Eingaben prüfen oder Bestandteile ersetzen. Entscheidend ist, welches Zeichen ein Musterelement beschreibt, worauf ein Quantor wirkt und ob du einen Teiltreffer oder die gesamte Zeichenkette prüfen möchtest.

Deine Lernziele

Hake ab, was du schon kannst — und komm am Ende hierher zurück!

Vom Text zum Muster

Stell dir vor, du suchst in vielen Zeichenketten nach einer bestimmten Form. Ein einzelnes Wort wie abc ist bereits ein einfaches Muster: Es trifft die genaue Zeichenfolge abc, auch als Teil einer längeren Zeichenkette.

Definition

Regulärer Ausdruck

Ein regulärer Ausdruck ist eine nach festen Regeln aufgebaute Beschreibung einer Menge von Zeichenketten. Beim Pattern Matching wird geprüft, ob ein Text oder ein Teil davon zu diesem Muster passt.

Ein Regex besteht aus zwei Arten von Zeichen:

  • Literale stehen für sich selbst. Im Muster Tag müssen T, a und g in dieser Reihenfolge vorkommen.
  • Metazeichen haben eine besondere Funktion. Dazu gehören beispielsweise ., *, +, ?, |, (, ), [ und ].

Das Muster ab*c verlangt ein a, danach beliebig viele b und anschließend ein c. Es passt daher zu ac, abc und abbbbc.

Merke

Lies ein Regex von links nach rechts. Bestimme zuerst die einzelnen Musterelemente und danach die Wirkung von Gruppen und Quantoren.

Teste dich
Frage 1 von 2LeichtWelche Zeichenkette passt vollständig zum Muster ab*c?
Lösung: abbbc — Der Stern wiederholt nur das unmittelbar vorherige b. Das Muster verlangt genau ein a, null oder mehr b und genau ein c.
Frage 2 von 2MittelWelche Beschreibung passt zu T.*g?
Lösung: Ein T, danach beliebig viele Zeichen und später ein g — Der Punkt steht in vielen Regex-Dialekten für ein beliebiges Einzelzeichen; der Stern erlaubt davon null oder mehr Wiederholungen.
Zeichen auswählen und wiederholen

Eine Zeichenklasse beschreibt genau ein Zeichen aus einer Auswahl. [abc] trifft also ein a, ein b oder ein c.

Bereiche verkürzen eine Auswahl:

  • [0-9] steht für eine Ziffer von 0 bis 9.
  • [a-c] steht für a, b oder c.
  • [A-Za-z] steht für einen der ausdrücklich angegebenen Groß- oder Kleinbuchstaben.
  • [^u] steht für ein einzelnes Zeichen außer u.

Der Punkt . ist in vielen Dialekten ein Platzhalter für fast jedes Einzelzeichen. Ob er auch einen Zeilenumbruch erfasst, hängt vom verwendeten Modus ab.

Ein Quantor bestimmt, wie oft das unmittelbar vorherige Element vorkommen darf:

  • *: null oder mehr Wiederholungen
  • +: eine oder mehr Wiederholungen
  • ?: null oder eine Wiederholung
  • {n}: genau n Wiederholungen
  • {n,m}: mindestens n, höchstens m Wiederholungen
  • {n,}: mindestens n Wiederholungen
Beispiel

Gesucht ist eine Hausnummer mit einer bis drei Ziffern ohne führende Null und einem optionalen Kleinbuchstaben.

Das Muster lautet:

[1-9][0-9]?[0-9]?[a-z]?

Der erste Teil [1-9] ist verpflichtend. Die beiden folgenden Ziffernklassen tragen jeweils ? und sind daher optional. Auch der Kleinbuchstabe ist optional.

Damit passen beispielsweise 7, 42, 128 und 12a. 012 passt nicht, weil die erste Ziffer keine Null sein darf. 1234 enthält eine Ziffer zu viel, wenn die gesamte Zeichenkette geprüft wird.

Klammern verändern, worauf ein Quantor wirkt. (ab)+ wiederholt den vollständigen Block ab; das Muster passt beispielsweise zu ab und abab. Ohne Klammern würde ab+ nur das b wiederholen.

Lückentext

Wähle in jeder Lücke die passende Form und prüfe anschließend deine Antworten.

Ein Quantor wirkt auf das unmittelbar ein. Der Stern erlaubt Wiederholungen. Die Klasse [0-9] beschreibt . Im Muster (ab)+ wird die wiederholt.

Lösungen: Lücke 1: vorherige Element; Lücke 2: null oder mehr; Lücke 3: eine Ziffer; Lücke 4: gesamte Gruppe. Prüfe bei jedem Quantor zuerst, welches einzelne Zeichen, welche Zeichenklasse oder welche geklammerte Gruppe direkt vor ihm steht.
Teiltreffer und vollständige Eingaben unterscheiden

Viele Suchfunktionen melden bereits einen Treffer, wenn nur ein Teil des Textes passt. [0-9]{2,5} findet in 1234507 beispielsweise die Teilzeichenkette 12345.

Soll die gesamte Zeichenkette aus zwei bis fünf Ziffern bestehen, werden in vielen Dialekten Anfang und Ende markiert:

^[0-9]{2,5}$

^ bezeichnet gewöhnlich den Anfang und $ das Ende der untersuchten Zeichenkette oder Zeile. Die genaue Bedeutung kann sich durch den Mehrzeilenmodus ändern. Manche Programmierschnittstellen bieten deshalb eine eigene Ganzstring-Prüfung an.

Beispiel

Für das Muster ^[0-9]{2,5}$ gilt:

  • 42 passt: zwei Ziffern.
  • 54072 passt: fünf Ziffern.
  • 7 passt nicht: zu kurz.
  • 123450 passt nicht: zu lang.
  • a42 passt nicht: Es enthält einen Buchstaben.

Ein Sonderzeichen muss geschützt werden, wenn du es als gewöhnliches Zeichen suchst. Der Punkt bedeutet normalerweise „beliebiges Zeichen“. \. verlangt dagegen einen echten Punkt. Das Muster 11\.10\.2019 passt deshalb zum Datum mit Punkten, aber nicht zu 11a10b2019.

Merke

Frage vor dem Testen: Suche ich einen passenden Ausschnitt oder soll die gesamte Eingabe dem Muster entsprechen?

Teste dich
Frage 1 von 2LeichtWarum findet [0-9]{2,5} einen Treffer in 1234507?
Lösung: Weil ein passender Teil mit fünf Ziffern enthalten ist — Ohne Ganzstring-Prüfung genügt eine passende Teilzeichenkette.
Frage 2 von 2MittelWelche Eingabe passt vollständig zu ^[0-9]{2,5}$?
Lösung: 9074 — Zwischen Anfang und Ende müssen ausschließlich zwei bis fünf Ziffern stehen.
Alternativen, Gruppen und Trefferauswahl

Der senkrechte Strich | trennt praktische Alternativen. Baum|Blume passt zu Baum oder Blume.

Klammern fassen mehrere Elemente zusammen. (Sonn|Frei)tag passt zu Sonntag oder Freitag. Ohne passende Gruppierung könnte die Alternative einen größeren Bereich erfassen als beabsichtigt.

Gruppen können in vielen Engines außerdem den gefundenen Text speichern. Eine solche Capturing-Gruppe lässt sich später beim Ersetzen oder über eine Rückwärtsreferenz wiederverwenden. Benötigst du den gespeicherten Teil nicht, unterstützen viele Dialekte eine nicht erfassende Gruppe wie (?:ab).

Gierig und zurückhaltend suchen

Quantoren sind gewöhnlich gierig: Sie erfassen zunächst so viel wie möglich, solange der Rest des Musters noch passen kann.

Beispiel

Auf dem Text ABCDEB trifft A.*B die gesamte Zeichenkette ABCDEB.

In Dialekten mit zurückhaltenden Quantoren trifft A.*?B dagegen nur AB, weil der Treffer beim ersten möglichen B endet.

Auch A[^B]*B endet hier beim ersten B: Die negierte Zeichenklasse erlaubt zwischen Anfang und Ende kein weiteres B.

Zurückhaltende und possessive Quantoren, Capturing, Rückwärtsreferenzen und Look-arounds sind Erweiterungen praktischer Engines. Ihre genaue Schreibweise und Unterstützung unterscheiden sich.

Teste dich
Frage 1 von 2MittelWelches Muster wiederholt den vollständigen Block cd mindestens einmal?
Lösung: (cd)+ — Klammern machen cd zu einem gemeinsamen Element; + wiederholt dieses Element mindestens einmal.
Frage 2 von 2SchwerWarum trifft A.*?B auf ABCDEB in einem unterstützenden Dialekt nur AB?
Lösung: Der zurückhaltende Quantor beendet den Treffer beim ersten möglichen B — Zurückhaltendes Matching nimmt die kürzeste Zeichenfolge, mit der das restliche Muster noch erfüllt wird.
Reguläre Ausdrücke als formale Sprachbeschreibung

In der theoretischen Informatik beschreibt ein regulärer Ausdruck nicht nur Fundstellen in einem Text, sondern eine formale Sprache.

Definition

Formale Sprache

Ein Alphabet ist eine endliche Menge von Zeichen. Ein Wort ist eine endliche Folge dieser Zeichen. Eine Sprache ist eine Menge solcher Wörter.

Die Grundbausteine theoretischer regulärer Ausdrücke sind:

  • : die leere Sprache, die kein Wort enthält
  • ε: das leere Wort, also ein Wort der Länge null
  • ein Alphabetzeichen wie a
  • Alternative beziehungsweise Vereinigung
  • Konkatenation, also Aneinanderfügen
  • Kleene-Stern *, also beliebig viele Wiederholungen einschließlich null

Für die Alternative wird theoretisch je nach Notation | oder + verwendet. Das ist eine wichtige Verwechslungsgefahr: In vielen praktischen Regex-Dialekten bedeutet + stattdessen „mindestens eine Wiederholung“.

Beispiel

Über dem Alphabet {a,b} beschreibt (a|b)(a|b) genau die vier Wörter aa, ab, ba und bb.

(ab)* beschreibt ε, ab, abab, ababab und so weiter. Das leere Wort gehört dazu, weil der Block auch nullmal wiederholt werden darf.

Dagegen beschreibt a*|b* nur Wörter aus lauter a oder lauter b. Gemischte Wörter wie ab gehören nicht dazu.

Merke

Ein Ausdruck ist eine Beschreibung; seine Sprache ist die Menge aller Wörter, die diese Beschreibung erfüllt.

Vom Ausdruck zum endlichen Automaten

Ein endlicher Automat besitzt endlich viele Zustände. Er liest ein Wort Zeichen für Zeichen, wechselt dabei den Zustand und entscheidet am Ende, ob das Wort akzeptiert wird.

Theoretische reguläre Ausdrücke und endliche Automaten sind gleich mächtig: Zu jedem regulären Ausdruck gibt es einen endlichen Automaten mit derselben Sprache, und zu jedem endlichen Automaten gibt es einen passenden regulären Ausdruck.

Betrachte die Sprache aller Binärwörter, die auf 1 enden. Ein Ausdruck dafür ist (0|1)*1.

Ein deterministischer Automat benötigt dafür zwei Zustände:

Aktueller ZustandEingabe 0Eingabe 1
q0: Start, nicht akzeptierendq0q1
q1: akzeptierendq0q1

Nach jeder gelesenen 1 steht der Automat in q1, nach jeder 0 in q0. Deshalb akzeptiert er genau die nichtleeren Wörter, deren letztes Zeichen 1 ist. 1, 01 und 101 werden akzeptiert; ε, 0 und 110 werden abgelehnt.

Für die systematische Umwandlung eines Ausdrucks in einen Automaten kann eine Konstruktion mit ε-Übergängen verwendet werden. In der Gegenrichtung lassen sich Zustände eliminieren oder Pfade schrittweise durch Ausdrücke beschreiben.

Teste dich
Frage 1 von 2MittelWelche Sprache beschreibt (ab)*?
Lösung: Beliebig viele vollständige Blöcke ab, einschließlich ε — Die Gruppe ab wird nullmal, einmal, zweimal oder öfter aneinandergereiht.
Frage 2 von 2SchwerWarum sind ein regulärer Ausdruck und ein passender endlicher Automat äquivalent?
Lösung: Beide beschreiben beziehungsweise akzeptieren genau dieselbe Wortmenge — Zwei Darstellungen sind hier äquivalent, wenn ihre Sprachen übereinstimmen.
Regex zuverlässig entwerfen und testen

Praktische Regex-Dialekte teilen viele Grundideen, sind aber nicht vollständig einheitlich. Unterschiede betreffen unter anderem Zeichenklassen, Anker, Unicode, Zeilenmodi, Capturing, Look-behind und die Schreibweise von Ersetzungen.

Gehe deshalb in fünf Schritten vor:

  1. Formuliere genau, welche Zeichenketten passen sollen.
  2. Zerlege die Bedingung in feste Zeichen, Auswahl, Reihenfolge und Wiederholungen.
  3. Entscheide zwischen Teiltreffer und Ganzstring-Prüfung.
  4. Bilde das Muster und erkläre jeden Teil.
  5. Teste passende, unpassende und grenzwertige Eingaben im vorgesehenen Dialekt.
Beispiel

Gesucht sind Zahlen mit einer bis zehn Ziffern ohne führende Null.

Das Muster [1-9][0-9]{0,9} beginnt mit einer Ziffer von 1 bis 9. Danach folgen null bis neun weitere Ziffern.

Gute Testfälle sind:

  • passend: 1, 42, 9876543210
  • unpassend: 0, 012, 12345678901
  • Grenzfälle: eine Ziffer und genau zehn Ziffern

Für eine Eingabeprüfung muss zusätzlich sichergestellt sein, dass nicht nur ein Teil der Eingabe getestet wird.

Komplexe Engine-Erweiterungen können über klassische reguläre Sprachen hinausgehen. Besonders Rückwärtsreferenzen vergleichen einen Treffer mit zuvor gespeichertem Text. Ein praktischer „Regex“ ist daher nicht immer ein regulärer Ausdruck im strengen theoretischen Sinn.

Gut zu wissen

Ein gutes Muster ist nicht bloß möglichst kurz. Es muss die beabsichtigten Fälle ausreichend genau erfassen, verständlich bleiben und im verwendeten Regex-Dialekt zuverlässig funktionieren.

Teste dich
Frage 1 von 1SchwerEin Muster soll genau zwei bis fünf Ziffern als vollständige Eingabe erlauben. Welche Testmenge deckt wichtige Fälle am besten ab?
Lösung: 7, 42, 54072, 123456 und 9a — Gute Tests enthalten gültige Fälle, zu kurze und zu lange Eingaben sowie falsche Zeichentypen. So werden Grenzen und Fehlannahmen sichtbar.
Karteikasten
Karteikasten

Überlege zuerst selbst und drehe die Karte anschließend zum Prüfen um.

Alles auf einen Blick
Mindmap
  • Regulärer Ausdruck
    • Muster lesen: Literale und Metazeichen
    • Zeichen auswählen: Zeichenklassen und Punkt
    • Häufigkeit festlegen: Quantoren
    • Struktur bilden: Gruppen und Alternativen
    • Treffer begrenzen: Anker oder Ganzstring-Prüfung
    • Verhalten prüfen: positive, negative und grenzwertige Fälle
    • Theorie verstehen: Sprache und endlicher Automat
Abschluss-Check
Teste dich
Frage 1 von 3LeichtWas bedeutet * in a*?
Lösung: Das a darf nullmal oder öfter vorkommen — Der Kleene-Stern schließt den Fall null Wiederholungen ein; deshalb gehört auch ε zur beschriebenen Sprache.
Frage 2 von 3MittelWelches Muster passt vollständig zu abab, aber nicht zu aba?
Lösung: ^(ab)+$ — Die Gruppe (ab) bildet den wiederholten Block. Anfang und Ende begrenzen die beabsichtigte vollständige Übereinstimmung im üblichen Modus.
Frage 3 von 3SchwerEin Automat über {0,1} wechselt bei jeder 0 nach q0 und bei jeder 1 nach q1; nur q1 akzeptiert. Welche Beschreibung ist gleichwertig?
Lösung: Alle nichtleeren Wörter, die mit 1 enden — Nach dem letzten gelesenen Zeichen zeigt der Zustand genau, ob dieses Zeichen 0 oder 1 war. Akzeptiert wird daher genau bei einer abschließenden 1; ein passender Ausdruck ist (0|1)*1.

Wenn du alle drei Antworten begründen kannst, kannst du Regex-Bausteine nicht nur erkennen, sondern zu einer gewünschten Zeichenmenge zusammensetzen und mit passenden Gegenbeispielen prüfen.

Passend dazu