Reguläre Ausdrücke: Ein praktischer Leitfaden mit Beispielen

· 12 Min. Lesezeit

Reguläre Ausdrücke (Regex) sind eines der mächtigsten Werkzeuge im Toolkit eines Entwicklers, werden aber oft missverstanden oder ganz gemieden. Ob du Benutzereingaben validierst, Logdateien analysierst oder Textdaten transformierst – Regex bietet eine prägnante und effiziente Möglichkeit, Muster in Zeichenketten zu finden.

Dieser umfassende Leitfaden führt dich von den Regex-Grundlagen zu fortgeschrittenen Techniken, mit praktischen Beispielen, die du sofort in deinen Projekten verwenden kannst. Am Ende wirst du nicht nur verstehen, wie Regex funktioniert, sondern auch wann und warum du es einsetzen solltest.

Inhaltsverzeichnis

Was ist Regex und warum sollte es dich interessieren?

Ein regulärer Ausdruck ist eine Zeichenfolge, die ein Suchmuster definiert. Stell es dir als eine Mini-Sprache vor, die speziell für das Musterabgleichen in Text entwickelt wurde. Anstatt nach exakten Zeichenketten zu suchen, ermöglicht dir Regex, Muster wie „jede E-Mail-Adresse" oder „alle Telefonnummern in diesem Format" zu beschreiben.

Regex wird in praktisch jeder Programmiersprache und vielen Kommandozeilen-Tools unterstützt. Sobald du die Syntax gelernt hast, kannst du sie überall anwenden – von JavaScript und Python bis zu grep und sed.

Häufige Anwendungsfälle sind:

Profi-Tipp: Obwohl Regex mächtig ist, ist es nicht immer das richtige Werkzeug. Für komplexe Parsing-Aufgaben wie HTML oder JSON solltest du dedizierte Parser verwenden. Regex funktioniert am besten für klar definierte, relativ einfache Muster.

Regex-Grundlagen: Bausteine

Jedes Regex-Muster besteht aus grundlegenden Bausteinen. Das Verständnis dieser Kernelemente ist essentiell, bevor du zu komplexeren Mustern übergehst.

Literale Zeichen

Der einfachste Regex ist einfach literaler Text. Das Muster cat findet die exakte Zeichenkette „cat" in deinem Text. Die meisten alphanumerischen Zeichen entsprechen sich selbst direkt.

Metazeichen

Bestimmte Zeichen haben in Regex spezielle Bedeutungen. Diese werden Metazeichen genannt und umfassen: . ^ $ * + ? { } [ ] \ | ( )

Um diese Zeichen literal zu finden, musst du sie mit einem Backslash maskieren. Zum Beispiel findet \. einen literalen Punkt.

Der Punkt-Platzhalter

Der Punkt . ist der grundlegendste Platzhalter – er findet jedes einzelne Zeichen außer Zeilenumbruch. Das Muster a.c findet „abc", „a1c", „a-c", aber nicht „ac" (kein Zeichen dazwischen) oder „a\nc" (Zeilenumbruch).

Muster Findet Beispiel
. Jedes Zeichen (außer Zeilenumbruch) a.c findet abc, a1c, a-c
\d Jede Ziffer [0-9] \d{3} findet 123, 456
\w Wortzeichen [a-zA-Z0-9_] \w+ findet hello, user_1
\s Leerzeichen (Leerzeichen, Tab, Zeilenumbruch) \s+ findet Leerzeichen, Tabs
\D Nicht-Ziffer \D+ findet abc, xyz
\W Nicht-Wortzeichen \W+ findet !@#, Leerzeichen
\S Nicht-Leerzeichen \S+ findet jeden sichtbaren Text

Beachte, dass Großbuchstaben-Versionen (\D, \W, \S) die Umkehrung ihrer Kleinbuchstaben-Gegenstücke sind. Das ist ein gängiges Muster in der Regex-Syntax.

Quantifizierer: Wiederholungen steuern

Quantifizierer geben an, wie oft ein Muster wiederholt werden soll. Sie werden nach dem Element platziert, das du wiederholen möchtest, und sind grundlegend für die Erstellung flexibler Muster.

Grundlegende Quantifizierer

Quantifizierer Bedeutung Beispiel
* 0 oder mehr Male ab*c findet ac, abc, abbc, abbbc
+ 1 oder mehr Male ab+c findet abc, abbc (nicht ac)
? 0 oder 1 Mal (optional) colou?r findet color, colour
{n} Genau n Male \d{4} findet 2026, 1999
{n,} n oder mehr Male \d{3,} findet 123, 1234, 12345
{n,m} Zwischen n und m Male \d{2,4} findet 12, 123, 1234

Gieriges vs. Genügsames Matching

Standardmäßig sind Quantifizierer gierig – sie finden so viel Text wie möglich. Das kann zu unerwarteten Ergebnissen führen, wenn man Muster wie HTML-Tags findet.

// Gieriges Matching
const text = "<div>Hallo</div><div>Welt</div>";
const greedy = /<.*>/;
// Findet: "<div>Hallo</div><div>Welt</div>" (gesamte Zeichenkette!)

// Genügsames Matching
const lazy = /<.*?>/;
// Findet: "<div>" (stoppt bei erster schließender Klammer)

Das Hinzufügen von ? nach einem Quantifizierer macht ihn genügsam (nicht-gierig). Genügsame Quantifizierer finden so wenig Text wie möglich, während sie das Muster noch erfüllen.

Schneller Tipp: Beim Finden von Inhalten zwischen Begrenzern (Anführungszeichen, Klammern, Tags) sind genügsame Quantifizierer normalerweise das, was du willst. Verwende .*? statt .*, um zu vermeiden, zu viel zu finden.

Zeichenklassen und Abkürzungen

Zeichenklassen ermöglichen es dir, jedes Zeichen aus einer bestimmten Menge zu finden. Sie werden mit eckigen Klammern definiert und sind unglaublich nützlich für die Erstellung flexibler Muster.

Grundlegende Zeichenklassen

// Findet jeden Vokal
/[aeiou]/

// Findet jede Ziffer
/[0-9]/

// Findet jeden Kleinbuchstaben
/[a-z]/

// Findet jeden Buchstaben (Groß-/Kleinschreibung unabhängig)
/[a-zA-Z]/

// Findet alphanumerische Zeichen
/[a-zA-Z0-9]/

Negierte Zeichenklassen

Verwende ^ am Anfang einer Zeichenklasse, um sie zu negieren – findet jedes Zeichen außer den aufgelisteten.

// Findet jede Nicht-Ziffer
/[^0-9]/

// Findet jeden Nicht-Vokal
/[^aeiou]/

// Findet jedes Zeichen außer Leerzeichen oder Tab
/[^ \t]/

Sonderzeichen in Klassen

Die meisten Metazeichen verlieren ihre spezielle Bedeutung innerhalb von Zeichenklassen. Du kannst ., *, + und ? ohne Maskierung einschließen. Allerdings musst du ], \, ^ und - in bestimmten Positionen noch maskieren.

// Findet einen Punkt oder ein Komma
/[.,]/

// Findet einen Bindestrich (maskieren oder am Anfang/Ende platzieren)
/[-a-z]/ oder /[a-z-]/

// Findet eine schließende Klammer (muss maskiert werden)
/[\]]/

Gruppen und Erfassungen

Gruppen dienen zwei Hauptzwecken: Sie ermöglichen es dir, Quantifizierer auf mehrere Zeichen anzuwenden, und sie erfassen gefundenen Text zur späteren Verwendung.

Erfassungsgruppen

Klammern erstellen Erfassungsgruppen, die sich den gefundenen Text merken. Das ist essentiell für die Extraktion von Daten aus Zeichenketten.

// Datumskomponenten extrahieren
const datePattern = /(\d{4})-(\d{2})-(\d{2})/;
const match = "2026-03-29".match(datePattern);

// match[0]: "2026-03-29" (vollständiger Treffer)
// match[1]: "2026" (erste Gruppe)
// match[2]: "03" (zweite Gruppe)
// match[3]: "29" (dritte Gruppe)

Benannte Erfassungsgruppen

Benannte Gruppen machen deinen Regex lesbarer und deinen Code wartbarer. Anstatt auf Gruppen per Nummer zu verweisen, gibst du ihnen beschreibende Namen.

// Syntax für benannte Gruppen: (?<name>pattern)
const datePattern = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
const match = "2026-03-29".match(datePattern);

// Zugriff per Name
console.log(match.groups.year);  // "2026"
console.log(match.groups.month); // "03"
console.log(match.groups.day);   // "29"

Nicht-erfassende Gruppen

Manchmal brauchst du Gruppierung für Quantifizierer oder Alternation, möchtest aber den Text nicht erfassen. Nicht-erfassende Gruppen verwenden die Syntax (?:...).

// Protokoll erfassen ohne eine Gruppe zu erstellen
/(?:https?|ftp):\/\/([a-z.]+)/

// Dies erstellt nur eine Erfassungsgruppe (die Domain)
// Die Protokollgruppe (?:https?|ftp) erfasst nicht

Nicht-erfassende Gruppen sind schneller und verbrauchen weniger Speicher als Erfassungsgruppen. Verwende sie, wenn du den erfassten Text nicht benötigst.

Rückverweise

Rückverweise ermöglichen es dir, denselben Text zu finden, der von einer vorherigen Gruppe erfasst wurde. Das ist nützlich zum Finden wiederholter Wörter oder zum Abgleichen gepaarter Begrenzer.

// Wiederholte Wörter finden
/\b(\w+)\s+\1\b/
// Findet "the the" oder "hello hello"

// Gepaarte Anführungszeichen finden
/(['"])(.*?)\1/
// Findet "hello" oder 'world' aber nicht "mixed'

Alternation

Der Pipe-Operator | erstellt Alternation – findet ein Muster oder ein anderes. Es ist wie ein logisches ODER.

// Findet cat, dog oder bird
/cat|dog|bird/

// Findet gängige Dateierweiterungen
/\.(jpg|jpeg|png|gif|webp)$/i

// Findet Mr., Mrs., Ms. oder Dr.
/(?:Mr|Mrs|Ms|Dr)\./

Anker und Grenzen

Anker finden keine Zeichen – sie finden Positionen in der Zeichenkette. Sie sind essentiell, um sicherzustellen, dass Muster an bestimmten Stellen erscheinen.

Zeichenketten-Anker

// Muss mit "Hello" beginnen
/^Hello/

// Muss mit "world" enden
/world$/

// Gesamte Zeichenkette muss genau 5 Ziffern sein
/^\d{5}$/

Wortgrenzen

Der \b-Anker findet Wortgrenzen – Positionen zwischen Wort- und Nicht-Wortzeichen. Das ist entscheidend für das Finden ganzer Wörter.

// Findet "cat" als ganzes Wort
/\bcat\b/
// Findet: "cat", "the cat sat"
// Findet nicht: "category", "scat"

// Findet Wörter, die mit "pre" beginnen
/\bpre\w+/
// Findet: "preview", "prepare", "prefix"

Die Umkehrung \B findet Nicht-Wortgrenzen – Positionen, wo beide Seiten Wortzeichen oder beide Nicht-Wortzeichen sind.

Profi-Tipp: Verwende immer Wortgrenzen, wenn du nach ganzen Wörtern suchst. Ohne sie wird die Suche nach "cat" auch "category" und "concatenate" finden. Das Muster \bcat\b stellt sicher, dass du nur das vollständige Wort findest.

Gängige Muster für die Praxis

Hier sind praxiserprobte Regex-Muster für gängige Validierungs- und Extraktionsaufgaben. Diese Muster balancieren Einfachheit mit praktischer Genauigkeit.

Mustertyp Regex Hinweise
E-Mail (einfach) ^[\w.-]+@[\w.-]+\.[a-zA-Z]{2,}$ Gut für grundlegende Validierung
E-Mail (RFC-konform) ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ Strenger, weithin akzeptiert
URL ^https?:\/\/[\w.-]+(?:\.[a-zA-Z]{2,})(?:\/\S*)?$ Grundlegende HTTP/HTTPS-URLs
IPv4-Adresse ^(?:\d{1,3}\.){3}\d{1,3}$ Nur Format, validiert keine Bereiche
IPv4 (streng) ^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$ Validiert 0-255-Bereich
Datum (JJJJ-MM-TT) ^\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01])$ ISO 8601-Format
Zeit (24-Stunden) ^(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d)?$ HH:MM oder HH:MM:SS
Telefon (US) ^\+?1?[-.\s]?\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}$ Flexible Formatierung
Hex-Farbe ^#(?:[0-9a-fA-F]{3}){1,2}$ 3- oder 6-stellige Hex-Codes
Kreditkarte ^\d{4}[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}$ Nur Format, verwende Luhn für Validierung
Benutzername ^[a-zA-Z0-9_-]{3,16}$ 3-16 Zeichen, alphanumerisch plus _ und -
Slug ^[a-z0-9]+(?:-[a-z0-9]+)*$ URL-freundlich, Kleinbuchstaben mit Bindestrichen

Passwort-Validierung

Passwort-Validierung erfordert die gleichzeitige Überprüfung mehrerer Bedingungen. Lookahead-Assertions machen dies ohne komplexe Logik möglich.

// Starkes Passwort: 8+ Zeichen, Großbuchstabe, Kleinbuchstabe, Ziffer, Sonderzeichen
/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/

// Aufschlüsselung:
// (?=.*[a-z])     - mindestens ein Kleinbuchstabe
// (?=.*[A-Z])     -