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?
- Regex-Grundlagen: Bausteine
- Quantifizierer: Wiederholungen steuern
- Zeichenklassen und Abkürzungen
- Gruppen und Erfassungen
- Anker und Grenzen
- Gängige Muster für die Praxis
- Flags: Regex-Verhalten ändern
- Fortgeschrittene Techniken
- Performance-Tipps und Best Practices
- Regex testen und debuggen
- Häufig gestellte Fragen
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:
- Validierung von Benutzereingaben (E-Mails, Telefonnummern, Passwörter)
- Datenextraktion aus Text (Logs parsen, Inhalte scrapen)
- Such- und Ersetzungsoperationen (Code refactoren, Daten bereinigen)
- URL-Routing und Musterabgleich
- Syntax-Highlighting und lexikalische Analyse
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
^findet den Anfang der Zeichenkette (oder Zeile im Mehrzeilen-Modus)$findet das Ende der Zeichenkette (oder Zeile im Mehrzeilen-Modus)
// 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]) -