Regex Cheat Sheet: Vollständiger Leitfaden zu Regulären Ausdrücken

Meistern Sie reguläre Ausdrücke mit diesem umfassenden Leitfaden. Lernen Sie Muster, Syntax, sprachspezifische Implementierungen (Python, JavaScript, PHP, C#, Java, Go, Ruby), Suchen-und-Ersetzen-Transformationen in VS Code und über 200 praktische Beispiele. Die ultimative Regex-Ressource für Anfänger und Experten.

G
GUi Softworks
60 Min. Lesezeit

Was ist eine Regex?

Reguläre Ausdrücke (Regex oder Regexp) sind Zeichenfolgen, die Suchmuster definieren. Sie sind eines der mächtigsten Werkzeuge für Textverarbeitung, Mustererkennung und Datenextraktion.

Warum Reguläre Ausdrücke verwenden?

Regex ist unverzichtbar für:

  • Formularvalidierung (E-Mail, Telefonnummern, Passwörter)
  • Datenextraktion (Log-Parsing, Web-Scraping)
  • Textverarbeitung (Suchen und Ersetzen, Formatierung)
  • Code-Refactoring (Variablen umbenennen, Syntax aktualisieren)
  • Eingabebereinigung (Sicherheit, Injection-Angriffe verhindern)

Wie man dieses Cheat Sheet liest

Dieser Leitfaden ist in progressive Abschnitte unterteilt:

  1. Grundlagen - Basissyntax und Muster
  2. Erweiterte Funktionen - Lookaround, benannte Gruppen, Unicode
  3. Sprachspezifisch - Beispiele in Python, JavaScript, PHP, C#, Java, Go, Ruby
  4. Regex in VS Code - Suchen-und-Ersetzen-Transformationen mit über 20 Beispielen
  5. Häufige Muster - Kopier- und einfügbare Muster für E-Mail, URL, Datum usw.
  6. Praktische Anwendungsfälle - Anwendungen aus der realen Welt
  7. Fehlerbehebung - Häufige Fehler und Performance-Tipps

Jeder Abschnitt enthält:

  • Klare Erklärungen
  • Visuelle Beispiele
  • Code-Schnipsel zum Kopieren
  • Profi-Tipps und Fallstricke

Literalzeichen

Die einfachste Regex ist eine Folge von Literalzeichen:

abc

Findet: "abc" in "Die Sequenz abc"

Groß-/Kleinschreibung

Standardmäßig sind Regex case-sensitive:

  • Hallo findet "Hallo" aber NICHT "hallo"
  • Verwenden Sie das i-Flag für case-insensitive Suche: /hallo/i

Sonderzeichen (Metazeichen)

Diese 12 Zeichen haben eine besondere Bedeutung in Regex und müssen mit \ maskiert werden, um literal zu suchen:

. ^ $ * + ? { } [ ] \ | ( )

Beispiele:

  • \. findet einen literalen Punkt
  • \€ findet ein Euro-Zeichen
  • \( findet eine literale Klammer
Zeichen Maskiert Beispiel Findet
. (Punkt) \. 3\.14 "3.14"
(Euro) \€ \€100 "€100"
* (Stern) \* a\*b "a*b"

Zeichenklassen

Vordefinierte Zeichenklassen

Muster Beschreibung Äquivalent Beispiel Findet
\d Beliebige Ziffer [0-9] \d\d "42"
\D Beliebige Nicht-Ziffer [^0-9] \D+ "abc"
\w Wortzeichen [a-zA-Z0-9_] \w+ "hallo_123"
\W Nicht-Wortzeichen [^a-zA-Z0-9_] \W "@", "#"
\s Leerzeichen [ \t\n\r\f\v] \s+ " " (Leerzeichen)
\S Nicht-Leerzeichen [^ \t\n\r\f\v] \S+ "hallo"
. Beliebiges Zeichen außer Zeilenumbruch - a.c "abc", "a1c"

Profi-Tipp: \w enthält standardmäßig KEINE Unicode-Buchstaben. Verwenden Sie \p{L} für Unicode-Unterstützung (JavaScript/Python).

Benutzerdefinierte Zeichenklassen

Muster Beschreibung Beispiel Findet
[abc] Findet eines von a, b oder c [aeiou] Vokale: "a", "e", "i", "o", "u"
[^abc] Findet alles außer a, b oder c [^0-9] Nicht-Ziffern
[a-z] Bereich: Kleinbuchstaben [a-z]+ "hallo"
[A-Z] Bereich: Großbuchstaben [A-Z]+ "HALLO"
[0-9] Bereich: Ziffern [0-9]{4} "2025"
[a-zA-Z] Kombiniert: alle Buchstaben [a-zA-Z0-9] Alphanumerisch

Beispiele:

[aeiou]       → Findet jeden Vokal
[^aeiou]      → Findet jeden Konsonanten (Nicht-Vokal)
[a-z0-9]      → Findet Kleinbuchstaben und Ziffern
[a-zA-Z0-9_]  → Entspricht \w (Wortzeichen)

Quantoren

Quantoren geben an, wie oft ein Muster gefunden werden soll.

Basis-Quantoren

Muster Beschreibung Beispiel Findet
* 0 oder mehr ab*c "ac", "abc", "abbc", "abbbc"
+ 1 oder mehr ab+c "abc", "abbc" (NICHT "ac")
? 0 oder 1 (optional) colou?r "color", "colour"
{n} Genau n mal \d{4} "2025" (genau 4 Ziffern)
{n,} n oder mehr mal \d{2,} "42", "123", "9999"
{n,m} Zwischen n und m mal \d{2,4} "42", "123", "2025"

Gierige vs. Nicht-gierige Quantoren

Gierig (Standard): Findet so viel wie möglich

<.*>      → Findet: "<div>Hallo</div>" (gesamte Zeichenkette)

Nicht-gierig (Lazy): Findet so wenig wie möglich (fügen Sie ? nach dem Quantor hinzu)

<.*?>     → Findet: "<div>" und "</div>" separat
Gierig Nicht-gierig Beschreibung
* *? 0 oder mehr (nicht-gierig)
+ +? 1 oder mehr (nicht-gierig)
? ?? 0 oder 1 (nicht-gierig)
{n,m} {n,m}? Zwischen n und m (nicht-gierig)

Beispiel:

Text: "Hallo" und "Welt"

  • ".*" findet: "Hallo" und "Welt" (gierig)
  • ".*?" findet: "Hallo" und "Welt" separat (nicht-gierig)

Anker und Grenzen

Anker finden Positionen, nicht Zeichen.

Muster Beschreibung Beispiel Findet
^ Anfang der Zeichenkette/Zeile ^Hallo "Hallo Welt" (am Anfang)
$ Ende der Zeichenkette/Zeile Welt$ "Hallo Welt" (am Ende)
\b Wortgrenze \bKatze\b "Katze" in "Die Katze saß" (NICHT "Raubkatze")
\B Nicht-Wortgrenze \BKatz "Raubkatze" (Katz NICHT an Grenze)
\A Anfang der Zeichenkette (nicht Zeile) \AHallo Findet nur wenn "Hallo" ganz am Anfang steht
\z Ende der Zeichenkette (nicht Zeile) Welt\z Findet nur wenn "Welt" ganz am Ende steht
\Z Ende der Zeichenkette (vor finalem Zeilenumbruch) Welt\Z Findet "Welt" oder "Welt\n"

Beispiele:

^Katze$       → Findet: "Katze" (gesamte Zeile ist "Katze")
\bKatze\b     → Findet: "Katze" in "die Katze saß" (ganzes Wort)
\BKatz        → Findet: "Katz" in "Raubkatze" (NICHT an Grenze)

Mehrzeilenmodus (Flag m):

  • Ohne m: ^ und $ finden Anfang/Ende der gesamten Zeichenkette
  • Mit m: ^ und $ finden Anfang/Ende jeder Zeile

Gruppen und Alternation

Erfassungsgruppen

Erfassungsgruppen (...) merken sich den gefundenen Text:

(\d+)-(\d+)   → Findet: "123-456"
                Gruppe 1: "123"
                Gruppe 2: "456"

Rückreferenzen (erfasste Gruppen wiederverwenden):

(\w)\1        → Findet: "aa", "bb", "cc" (wiederholtes Zeichen)
(\w+) \1      → Findet: "hallo hallo" (wiederholtes Wort)

Nicht-erfassende Gruppen

Verwenden Sie (?:...) wenn Sie gruppieren aber nicht erfassen möchten:

(?:https?://)  → Gruppiert "http://" oder "https://" ohne zu erfassen

Warum nicht-erfassend verwenden?

  • Bessere Performance (kein Speicher-Overhead)
  • Sauberere Rückreferenzen (nur Erfassungsgruppen werden nummeriert)

Alternation (ODER)

Verwenden Sie | für "findet dies ODER das":

Katze|Hund    → Findet: "Katze" oder "Hund"
gr(a|ü)n      → Findet: "gran" oder "grün"

Beispiele:

(Herr|Frau|Dr)\.?  → Findet: "Herr", "Frau", "Dr."
https?://          → Findet: "http://" oder "https://"

Lookaround-Zusicherungen

Lookarounds sind Null-Breiten-Zusicherungen, die eine Position finden (wie Anker), aber mit Bedingungen.

Positiver Lookahead (?=...)

Findet, wenn das Muster voraus passt (aber konsumiert es nicht):

\d(?=px)      → Findet: "10" in "10px" (NICHT der "px"-Teil)

Anwendungsfall: Passwort-Validierung

^(?=.*[A-Z])(?=.*[a-z])(?=.*\d)(?=.*[@$!%*?&]).{8,}$

Aufschlüsselung:

  • (?=.*[A-Z]) - Muss Großbuchstaben enthalten
  • (?=.*[a-z]) - Muss Kleinbuchstaben enthalten
  • (?=.*\d) - Muss Ziffer enthalten
  • (?=.*[@$!%*?&]) - Muss Sonderzeichen enthalten
  • .{8,} - Mindestens 8 Zeichen

Negativer Lookahead (?!...)

Findet, wenn das Muster voraus NICHT passt:

\d(?!px)      → Findet: "10" in "10em" (NICHT "10px")

Anwendungsfall: Bestimmte Wörter ausschließen

\b(?!test)\w+  → Findet Wörter, die NICHT mit "test" beginnen

Positiver Lookbehind (?<=...)

Findet, wenn das Muster rückwärts passt:

(?<=€)\d+     → Findet: "100" in "€100" (NICHT der "€"-Teil)

Anwendungsfall: Preise extrahieren

(?<=Preis: €)\d+,\d{2}  → Findet: "29,99" in "Preis: €29,99"

Negativer Lookbehind (?<!...)

Findet, wenn das Muster rückwärts NICHT passt:

(?<!€)\d+     → Findet: "100" aber NICHT in "€100"

Zusammenfassungstabelle:

Typ Syntax Beschreibung Beispiel
Positiver Lookahead (?=...) Findet wenn gefolgt von... q(?=u) findet "q" in "queen"
Negativer Lookahead (?!...) Findet wenn NICHT gefolgt von... q(?!u) findet "q" in "iraq"
Positiver Lookbehind (?<=...) Findet wenn vorangestellt von... (?<=€)\d+ findet "10" in "€10"
Negativer Lookbehind (?<!...) Findet wenn NICHT vorangestellt von... (?<!€)\d+ findet "10" in "10"

Benannte Erfassungsgruppen

Benannte Gruppen (?<name>...) machen Regex lesbarer:

JavaScript:

const dateRegex = /(?<jahr>\d{4})-(?<monat>\d{2})-(?<tag>\d{2})/;
const match = '2025-01-17'.match(dateRegex);

console.log(match.groups.jahr);   // "2025"
console.log(match.groups.monat);  // "01"
console.log(match.groups.tag);    // "17"

Python:

import re

pattern = r'(?P<jahr>\d{4})-(?P<monat>\d{2})-(?P<tag>\d{2})'
match = re.search(pattern, '2025-01-17')

print(match.group('jahr'))   # "2025"
print(match.group('monat'))  # "01"
print(match.group('tag'))    # "17"

C#:

var pattern = @"(?<jahr>\d{4})-(?<monat>\d{2})-(?<tag>\d{2})";
var match = Regex.Match("2025-01-17", pattern);

Console.WriteLine(match.Groups["jahr"].Value);   // "2025"

Atomare Gruppen und Possessive Quantoren

Atomare Gruppen (?>...)

Sobald gefunden, gibt es kein Backtracking. Verhindert katastrophales Backtracking:

(?>\d+)bar    → Findet: "123bar" (schnell)

Ohne atomare Gruppe:

\d+bar        → Versucht: "123bar", "12bar", "1bar" (langsam bei Nichtübereinstimmung)

Possessive Quantoren

Gierig Possessiv Beschreibung
* *+ 0 oder mehr (kein Backtracking)
+ ++ 1 oder mehr (kein Backtracking)
? ?+ 0 oder 1 (kein Backtracking)

Anwendungsfall: Katastrophales Backtracking bei komplexen Mustern verhindern.


Unicode-Unterstützung

Moderne Regex-Engines unterstützen Unicode-Kategorien und Skripte.

Unicode-Kategorien \p{...}

JavaScript (ES2018+):

const letters = /\p{L}+/u;     // Beliebiger Buchstabe (jede Sprache)
const numbers = /\p{N}+/u;     // Beliebige Zahl
const currency = /\p{Sc}/u;    // Währungssymbole

Python:

import regex  # Hinweis: benötigt 'regex'-Modul, nicht 're'

letters = regex.compile(r'\p{L}+')

Häufige Unicode-Kategorien:

Kategorie Beschreibung Beispiel
\p{L} Buchstabe "a", "字", "א"
\p{N} Zahl "1", "①", "一"
\p{S} Symbol "$", "©", "♥"
\p{Sc} Währungssymbol "$", "€", "¥"
\p{P} Interpunktion ".", "!", "?"
\p{Z} Trennzeichen Leerzeichen, Tab

Unicode-Skripte:

/\p{Script=Greek}/u     → Findet griechische Buchstaben: "α", "β", "γ"
/\p{Script=Cyrillic}/u  → Findet kyrillisch: "а", "б", "в"
/\p{Script=Han}/u       → Findet chinesische Zeichen

Negation:

/\P{L}+/u   → Findet alles, was KEIN Buchstabe ist

Modifikatoren und Flags

Flags ändern, wie Regex-Muster interpretiert werden.

Flag Name Beschreibung Beispiel
i Case-insensitive Ignoriert Groß-/Kleinschreibung /hallo/i findet "Hallo"
g Global Findet alle Übereinstimmungen /katze/g findet alle "katze"
m Multiline ^ und $ finden Zeilenanfänge/-enden /^hallo/m
s Dotall . findet auch Zeilenumbruch /a.b/s findet "a\nb"
u Unicode Aktiviert Unicode-Funktionen /\p{L}+/u
x Extended Ignoriert Leerzeichen (Free-Spacing) Erlaubt Kommentare
y Sticky Findet an exakter Position Nur JavaScript

Beispiele:

Case-insensitive (i):

/hallo/i.test('HALLO')   // true

Global (g):

'katze hund katze'.match(/katze/g)   // ["katze", "katze"]

Multiline (m):

const text = 'Zeile 1\nZeile 2';
/^Zeile 2/m.test(text)   // true (ohne 'm': false)

Dotall (s):

/a.b/s.test('a\nb')   // true (ohne 's': false)

Inline-Modifikatoren

Flags auf Teil des Musters anwenden:

(?i)hallo       → "hallo" case-insensitive
(?-i)WELT       → "WELT" case-sensitive
(?i:hallo)      → Nur "hallo" ist case-insensitive

Bedingte Muster

Syntax: (?(Bedingung)wahr|falsch)

Beispiel: Zitierte oder unzitierte Zeichenketten finden

("|')?[^"'\r\n]*(?(1)\1)

Aufschlüsselung:

  • ("|')? - Erfasst optional öffnendes Anführungszeichen
  • [^"'\r\n]* - Findet Inhalt
  • (?(1)\1) - Wenn Gruppe 1 gefunden (öffnendes Anführungszeichen), finde gleiches schließendes Anführungszeichen

Findet:

  • "hallo"
  • 'welt'
  • test ✅ (keine Anführungszeichen)
  • "gemischt' ❌ (unpassende Anführungszeichen)

Kommentare in Regex

Inline-Kommentare (?# kommentar)

\d{3}(?# Vorwahl)-\d{3}(?# Zentrale)-\d{4}(?# Nummer)

Free-Spacing-Modus (Flag x)

Ignoriert Leerzeichen und erlaubt Kommentare:

(?x)
  \d{3}     # Vorwahl
  -         # Trennzeichen
  \d{3}     # Zentrale
  -         # Trennzeichen
  \d{4}     # Nummer

Viel lesbarer für komplexe Muster!

Dieser Abschnitt zeigt, wie Regex in 7 beliebten Programmiersprachen verwendet wird. Jede Sprache hat ihre eigene Regex-API, aber die Mustersyntax bleibt größtenteils konsistent.

JavaScript / Node.js

Regex-Muster erstellen

// Literal-Notation (am häufigsten)
const pattern1 = /\d{3}-\d{4}/;

// Konstruktor (wenn Muster dynamisch ist)
const pattern2 = new RegExp('\\d{3}-\\d{4}');
// Hinweis: Backslashes müssen in Strings maskiert werden

// Mit Flags
const pattern3 = /hallo/gi;  // Global, case-insensitive

String-Methoden

// .match() - Findet Übereinstimmungen
const text = 'Kontakt: 123-4567 oder 987-6543';
const matches = text.match(/\d{3}-\d{4}/g);
console.log(matches);  // ["123-4567", "987-6543"]

// .matchAll() - Holt alle Übereinstimmungen mit Gruppen (ES2020)
const emailPattern = /([\w.-]+)@([\w.-]+\.[a-z]{2,})/gi;
const emails = 'admin@beispiel.de, benutzer@test.org';
for (const match of emails.matchAll(emailPattern)) {
  console.log(`Benutzer: ${match[1]}, Domain: ${match[2]}`);
}
// Benutzer: admin, Domain: beispiel.de
// Benutzer: benutzer, Domain: test.org

// .search() - Findet Position der ersten Übereinstimmung
const pos = 'Hallo Welt'.search(/Welt/);
console.log(pos);  // 6

// .replace() - Ersetzt Übereinstimmungen
const phone = '(+49) 151 123 4567';
const cleaned = phone.replace(/[^\d]/g, '');
console.log(cleaned);  // "491511234567"

// .replaceAll() - Ersetzt alle Übereinstimmungen (ES2021)
const text2 = 'katze hund katze';
const result = text2.replaceAll(/katze/g, 'vogel');
console.log(result);  // "vogel hund vogel"

// .split() - Teilt nach Muster
const csv = 'apfel,banane, orange , traube';
const fruits = csv.split(/\s*,\s*/);
console.log(fruits);  // ["apfel", "banane", "orange", "traube"]

RegExp-Methoden

// .test() - Gibt Boolean zurück
const isEmail = /^[\w.-]+@[\w.-]+\.[a-z]{2,}$/i;
console.log(isEmail.test('benutzer@beispiel.de'));  // true

// .exec() - Gibt Übereinstimmungsdetails zurück (oder null)
const pattern = /(\d{4})-(\d{2})-(\d{2})/;
const match = pattern.exec('Datum: 2025-01-17');
if (match) {
  console.log(match[0]);  // "2025-01-17" (vollständige Übereinstimmung)
  console.log(match[1]);  // "2025" (Gruppe 1)
  console.log(match[2]);  // "01" (Gruppe 2)
  console.log(match[3]);  // "17" (Gruppe 3)
}

Benannte Gruppen (ES2018+)

const pattern = /(?<jahr>\d{4})-(?<monat>\d{2})-(?<tag>\d{2})/;
const match = '2025-01-17'.match(pattern);

console.log(match.groups.jahr);   // "2025"
console.log(match.groups.monat);  // "01"
console.log(match.groups.tag);    // "17"

// Benannte Rückreferenzen
const dupeWord = /\b(?<wort>\w+)\s+\k<wort>\b/i;
console.log(dupeWord.test('hallo hallo'));  // true

Unicode-Unterstützung (ES2018+)

// Findet beliebigen Buchstaben (inkl. umlaute, chinesisch, arabisch, etc.)
const letters = /\p{L}+/u;
console.log(letters.test('Kaffee'));  // true
console.log(letters.test('你好'));    // true

// Findet Emoji
const emoji = /\p{Emoji}/u;
console.log(emoji.test('Hallo 👋'));  // true

Python

Das re-Modul

import re

# Muster kompilieren (empfohlen für Wiederverwendung)
pattern = re.compile(r'\d{3}-\d{4}')

# Oder direkt verwenden
re.search(r'\d{3}-\d{4}', 'Rufen Sie an 123-4567')

Kern-Funktionen

import re

# re.search() - Findet erste Übereinstimmung
match = re.search(r'\d{3}-\d{4}', 'Kontakt: 123-4567 oder 987-6543')
if match:
    print(match.group())  # "123-4567"
    print(match.start())  # 9 (Position)
    print(match.end())    # 17

# re.match() - Findet am ANFANG der Zeichenkette
match = re.match(r'\d+', '123 Hauptstraße')
print(match.group() if match else None)  # "123"

match = re.match(r'\d+', 'Hauptstraße 123')
print(match)  # None (beginnt nicht mit Ziffer)

# re.fullmatch() - Findet GESAMTE Zeichenkette
result = re.fullmatch(r'\d{3}-\d{4}', '123-4567')
print(bool(result))  # True

result = re.fullmatch(r'\d{3}-\d{4}', 'Rufen Sie an 123-4567')
print(bool(result))  # False (zusätzlicher Text)

# re.findall() - Findet alle Übereinstimmungen (gibt Liste zurück)
text = 'Preise: €10, €25, €100'
prices = re.findall(r'€(\d+)', text)
print(prices)  # ['10', '25', '100']

# re.finditer() - Findet alle Übereinstimmungen (gibt Iterator zurück)
for match in re.finditer(r'€(\d+)', text):
    print(f'Gefunden €{match.group(1)} an Position {match.start()}')
# Gefunden €10 an Position 7
# Gefunden €25 an Position 12
# Gefunden €100 an Position 17

# re.sub() - Ersetzt Übereinstimmungen
phone = '(+49) 151 123 4567'
cleaned = re.sub(r'[^\d]', '', phone)
print(cleaned)  # "491511234567"

# re.split() - Teilt nach Muster
csv = 'apfel,banane, orange , traube'
fruits = re.split(r'\s*,\s*', csv)
print(fruits)  # ['apfel', 'banane', 'orange', 'traube']

Gruppen und benannte Gruppen

import re

# Nummerierte Gruppen
pattern = r'(\d{4})-(\d{2})-(\d{2})'
match = re.search(pattern, 'Datum: 2025-01-17')
if match:
    print(match.group(0))  # "2025-01-17" (vollständige Übereinstimmung)
    print(match.group(1))  # "2025"
    print(match.group(2))  # "01"
    print(match.group(3))  # "17"
    print(match.groups())  # ('2025', '01', '17')

# Benannte Gruppen (?P<name>...)
pattern = r'(?P<jahr>\d{4})-(?P<monat>\d{2})-(?P<tag>\d{2})'
match = re.search(pattern, '2025-01-17')
if match:
    print(match.group('jahr'))    # "2025"
    print(match.group('monat'))   # "01"
    print(match.group('tag'))     # "17"
    print(match.groupdict())      # {'jahr': '2025', 'monat': '01', 'tag': '17'}

Flags

import re

# Case-insensitive
re.search(r'hallo', 'HALLO', re.IGNORECASE)  # oder re.I

# Multiline (^ und $ finden Zeilenanfänge/-enden)
re.search(r'^Zeile 2', 'Zeile 1\nZeile 2', re.MULTILINE)  # oder re.M

# Dotall (. findet Zeilenumbruch)
re.search(r'a.b', 'a\nb', re.DOTALL)  # oder re.S

# Verbose (Free-Spacing-Modus mit Kommentaren)
pattern = re.compile(r'''
    \d{3}     # Vorwahl
    -         # Trennzeichen
    \d{3}     # Zentrale
    -         # Trennzeichen
    \d{4}     # Nummer
''', re.VERBOSE)  # oder re.X

# Flags kombinieren mit |
pattern = re.compile(r'hallo', re.IGNORECASE | re.MULTILINE)

Ersetzen mit Funktionen

import re

# Funktion für dynamische Ersetzungen verwenden
def double_number(match):
    num = int(match.group())
    return str(num * 2)

text = 'Ich habe 5 Äpfel und 10 Orangen'
result = re.sub(r'\d+', double_number, text)
print(result)  # "Ich habe 10 Äpfel und 20 Orangen"

# Mit benannten Gruppen
def format_name(match):
    return f"{match.group('nachname').upper()}, {match.group('vorname')}"

pattern = r'(?P<vorname>\w+)\s+(?P<nachname>\w+)'
text = 'Hans Müller'
result = re.sub(pattern, format_name, text)
print(result)  # "MÜLLER, Hans"

PHP

PCRE-Funktionen

<?php

// preg_match() - Findet erste Übereinstimmung
$pattern = '/\d{3}-\d{4}/';
$text = 'Kontakt: 123-4567 oder 987-6543';

if (preg_match($pattern, $text, $matches)) {
    echo $matches[0];  // "123-4567"
}

// preg_match_all() - Findet alle Übereinstimmungen
preg_match_all('/\d{3}-\d{4}/', $text, $matches);
print_r($matches[0]);  // ["123-4567", "987-6543"]

// preg_replace() - Ersetzt Übereinstimmungen
$phone = '(+49) 151 123 4567';
$cleaned = preg_replace('/[^\d]/', '', $phone);
echo $cleaned;  // "491511234567"

// preg_split() - Teilt nach Muster
$csv = 'apfel,banane, orange , traube';
$fruits = preg_split('/\s*,\s*/', $csv);
print_r($fruits);  // ["apfel", "banane", "orange", "traube"]

// preg_grep() - Filtert Array nach Muster
$words = ['apfel', 'banane', 'aprikose', 'orange'];
$aWords = preg_grep('/^a/', $words);
print_r($aWords);  // ["apfel", "aprikose"]
?>

Benannte Gruppen

<?php
$pattern = '/(?P<jahr>\d{4})-(?P<monat>\d{2})-(?P<tag>\d{2})/';
$text = '2025-01-17';

if (preg_match($pattern, $text, $matches)) {
    echo $matches['jahr'];   // "2025"
    echo $matches['monat'];  // "01"
    echo $matches['tag'];    // "17"
}
?>

Modifikatoren (Flags)

<?php
// i - Case-insensitive
preg_match('/hallo/i', 'HALLO');  // Findet

// m - Multiline
preg_match('/^Zeile 2/m', "Zeile 1\nZeile 2");  // Findet

// s - Dotall (. findet Zeilenumbruch)
preg_match('/a.b/s', "a\nb");  // Findet

// x - Free-Spacing (ignoriert Leerzeichen)
$pattern = '/
    \d{3}     # Vorwahl
    -         # Trennzeichen
    \d{3}     # Zentrale
    -         # Trennzeichen
    \d{4}     # Nummer
/x';

// u - UTF-8-Unterstützung
preg_match('/\w+/u', 'Kaffee');  // Findet (inkl. ü)

// Modifikatoren kombinieren
preg_match('/hallo/imu', $text);
?>

Ersetzen mit Callback

<?php
$text = 'Ich habe 5 Äpfel und 10 Orangen';

$result = preg_replace_callback('/\d+/', function($matches) {
    return (int)$matches[0] * 2;
}, $text);

echo $result;  // "Ich habe 10 Äpfel und 20 Orangen"
?>

C# (.NET)

Regex-Klasse

using System;
using System.Text.RegularExpressions;

// Statische Methoden (einfache Verwendung)
string text = "Kontakt: 123-4567 oder 987-6543";
Match match = Regex.Match(text, @"\d{3}-\d{4}");
if (match.Success)
{
    Console.WriteLine(match.Value);  // "123-4567"
}

// Findet alle Übereinstimmungen
MatchCollection matches = Regex.Matches(text, @"\d{3}-\d{4}");
foreach (Match m in matches)
{
    Console.WriteLine(m.Value);
}
// Ausgabe:
// 123-4567
// 987-6543

// Ersetzen
string phone = "(+49) 151 123 4567";
string cleaned = Regex.Replace(phone, @"[^\d]", "");
Console.WriteLine(cleaned);  // "491511234567"

// Teilen
string csv = "apfel,banane, orange , traube";
string[] fruits = Regex.Split(csv, @"\s*,\s*");
// ["apfel", "banane", "orange", "traube"]

Kompilierte Regex (Bessere Performance)

using System.Text.RegularExpressions;

// Kompilieren für Wiederverwendung (viel schneller bei wiederholter Verwendung)
Regex pattern = new Regex(@"\d{3}-\d{4}", RegexOptions.Compiled);

string text = "Kontakt: 123-4567";
Match match = pattern.Match(text);
if (match.Success)
{
    Console.WriteLine(match.Value);
}

RegexOptions (Flags)

using System.Text.RegularExpressions;

// Case-insensitive
Regex.IsMatch("HALLO", "hallo", RegexOptions.IgnoreCase);

// Multiline
Regex.Match("Zeile 1\nZeile 2", "^Zeile 2", RegexOptions.Multiline);

// Singleline (. findet Zeilenumbruch)
Regex.Match("a\nb", "a.b", RegexOptions.Singleline);

// Compiled (bessere Performance)
var pattern = new Regex(@"\d+", RegexOptions.Compiled);

// Optionen kombinieren
var opts = RegexOptions.IgnoreCase | RegexOptions.Multiline;
Regex.Match(text, pattern, opts);

Benannte Gruppen

using System;
using System.Text.RegularExpressions;

string pattern = @"(?<jahr>\d{4})-(?<monat>\d{2})-(?<tag>\d{2})";
Match match = Regex.Match("2025-01-17", pattern);

if (match.Success)
{
    Console.WriteLine(match.Groups["jahr"].Value);   // "2025"
    Console.WriteLine(match.Groups["monat"].Value);  // "01"
    Console.WriteLine(match.Groups["tag"].Value);    // "17"
}

Ersetzen mit MatchEvaluator

using System;
using System.Text.RegularExpressions;

string text = "Ich habe 5 Äpfel und 10 Orangen";

string result = Regex.Replace(text, @"\d+", match =>
{
    int num = int.Parse(match.Value);
    return (num * 2).ToString();
});

Console.WriteLine(result);  // "Ich habe 10 Äpfel und 20 Orangen"

Java

Pattern- und Matcher-Klassen

import java.util.regex.Pattern;
import java.util.regex.Matcher;

// Muster kompilieren
Pattern pattern = Pattern.compile("\\d{3}-\\d{4}");
String text = "Kontakt: 123-4567 oder 987-6543";

// Matcher erstellen
Matcher matcher = pattern.matcher(text);

// Erste Übereinstimmung finden
if (matcher.find()) {
    System.out.println(matcher.group());  // "123-4567"
}

// Alle Übereinstimmungen finden
matcher.reset();  // Auf Anfang zurücksetzen
while (matcher.find()) {
    System.out.println(matcher.group());
}
// Ausgabe:
// 123-4567
// 987-6543

String-Methoden

// matches() - Prüft ob GESAMTE Zeichenkette passt
boolean isPhone = "123-4567".matches("\\d{3}-\\d{4}");
System.out.println(isPhone);  // true

// replaceAll() - Ersetzt alle Übereinstimmungen
String phone = "(+49) 151 123 4567";
String cleaned = phone.replaceAll("[^\\d]", "");
System.out.println(cleaned);  // "491511234567"

// replaceFirst() - Ersetzt erste Übereinstimmung
String text = "katze hund katze";
String result = text.replaceFirst("katze", "vogel");
System.out.println(result);  // "vogel hund katze"

// split() - Teilt nach Muster
String csv = "apfel,banane, orange , traube";
String[] fruits = csv.split("\\s*,\\s*");
// ["apfel", "banane", "orange", "traube"]

Pattern-Flags

import java.util.regex.Pattern;

// Case-insensitive
Pattern pattern = Pattern.compile("hallo", Pattern.CASE_INSENSITIVE);

// Multiline
Pattern.compile("^Zeile 2", Pattern.MULTILINE);

// Dotall (. findet Zeilenumbruch)
Pattern.compile("a.b", Pattern.DOTALL);

// Kommentare (Free-Spacing)
Pattern.compile("""
    \\d{3}     # Vorwahl
    -          # Trennzeichen
    \\d{3}     # Zentrale
    -          # Trennzeichen
    \\d{4}     # Nummer
    """, Pattern.COMMENTS);

// Flags kombinieren
int flags = Pattern.CASE_INSENSITIVE | Pattern.MULTILINE;
Pattern.compile("pattern", flags);

Benannte Gruppen

import java.util.regex.Pattern;
import java.util.regex.Matcher;

Pattern pattern = Pattern.compile("(?<jahr>\\d{4})-(?<monat>\\d{2})-(?<tag>\\d{2})");
Matcher matcher = pattern.matcher("2025-01-17");

if (matcher.find()) {
    System.out.println(matcher.group("jahr"));   // "2025"
    System.out.println(matcher.group("monat"));  // "01"
    System.out.println(matcher.group("tag"));    // "17"
}

Erweitertes Ersetzen

import java.util.regex.Pattern;
import java.util.regex.Matcher;

String text = "Ich habe 5 Äpfel und 10 Orangen";
Pattern pattern = Pattern.compile("\\d+");
Matcher matcher = pattern.matcher(text);

StringBuffer result = new StringBuffer();
while (matcher.find()) {
    int num = Integer.parseInt(matcher.group());
    matcher.appendReplacement(result, String.valueOf(num * 2));
}
matcher.appendTail(result);

System.out.println(result);  // "Ich habe 10 Äpfel und 20 Orangen"

Go (Golang)

Das regexp-Paket

package main

import (
    "fmt"
    "regexp"
)

func main() {
    // Muster kompilieren
    pattern := regexp.MustCompile(`\d{3}-\d{4}`)
    text := "Kontakt: 123-4567 oder 987-6543"

    // Erste Übereinstimmung finden
    match := pattern.FindString(text)
    fmt.Println(match)  // "123-4567"

    // Alle Übereinstimmungen finden
    matches := pattern.FindAllString(text, -1)
    fmt.Println(matches)  // [123-4567 987-6543]

    // Prüfen ob passt
    isMatch := pattern.MatchString("123-4567")
    fmt.Println(isMatch)  // true

    // Alles ersetzen
    phone := "(+49) 151 123 4567"
    cleaned := regexp.MustCompile(`[^\d]`).ReplaceAllString(phone, "")
    fmt.Println(cleaned)  // "491511234567"

    // Teilen
    csv := "apfel,banane, orange , traube"
    fruits := regexp.MustCompile(`\s*,\s*`).Split(csv, -1)
    fmt.Println(fruits)  // [apfel banane orange traube]
}

Submatch (Gruppen)

package main

import (
    "fmt"
    "regexp"
)

func main() {
    pattern := regexp.MustCompile(`(\d{4})-(\d{2})-(\d{2})`)
    text := "Datum: 2025-01-17"

    // FindStringSubmatch gibt [vollständig, gruppe1, gruppe2, ...] zurück
    matches := pattern.FindStringSubmatch(text)
    if matches != nil {
        fmt.Println(matches[0])  // "2025-01-17" (vollständige Übereinstimmung)
        fmt.Println(matches[1])  // "2025" (Gruppe 1)
        fmt.Println(matches[2])  // "01" (Gruppe 2)
        fmt.Println(matches[3])  // "17" (Gruppe 3)
    }

    // FindAllStringSubmatch für alle Übereinstimmungen
    text2 := "Datum: 2025-01-17 und 2024-12-31"
    allMatches := pattern.FindAllStringSubmatch(text2, -1)
    for _, match := range allMatches {
        fmt.Printf("Jahr: %s, Monat: %s, Tag: %s\n", match[1], match[2], match[3])
    }
    // Jahr: 2025, Monat: 01, Tag: 17
    // Jahr: 2024, Monat: 12, Tag: 31
}

Benannte Gruppen

package main

import (
    "fmt"
    "regexp"
)

func main() {
    pattern := regexp.MustCompile(`(?P<jahr>\d{4})-(?P<monat>\d{2})-(?P<tag>\d{2})`)
    text := "2025-01-17"

    match := pattern.FindStringSubmatch(text)
    if match != nil {
        // Benannte Gruppenindizes abrufen
        names := pattern.SubexpNames()
        result := make(map[string]string)
        for i, name := range names {
            if i != 0 && name != "" {
                result[name] = match[i]
            }
        }
        fmt.Println(result["jahr"])   // "2025"
        fmt.Println(result["monat"])  // "01"
        fmt.Println(result["tag"])    // "17"
    }
}

Ersetzen mit Funktionen

package main

import (
    "fmt"
    "regexp"
    "strconv"
)

func main() {
    text := "Ich habe 5 Äpfel und 10 Orangen"
    pattern := regexp.MustCompile(`\d+`)

    result := pattern.ReplaceAllStringFunc(text, func(s string) string {
        num, _ := strconv.Atoi(s)
        return strconv.Itoa(num * 2)
    })

    fmt.Println(result)  // "Ich habe 10 Äpfel und 20 Orangen"
}

Ruby

Regex-Literale

# Literal-Notation
pattern = /\d{3}-\d{4}/

# Mit Flags
pattern_ci = /hallo/i  # Case-insensitive
pattern_multi = /^zeile/m  # Multiline

# Konstruktor (für dynamische Muster)
pattern = Regex.new('\d{3}-\d{4}')

String-Methoden

text = 'Kontakt: 123-4567 oder 987-6543'

# match() - Gibt MatchData oder nil zurück
match = text.match(/\d{3}-\d{4}/)
if match
  puts match[0]  # "123-4567"
end

# scan() - Findet alle Übereinstimmungen
matches = text.scan(/\d{3}-\d{4}/)
puts matches  # ["123-4567", "987-6543"]

# =~ Operator - Gibt Index der ersten Übereinstimmung zurück
index = text =~ /\d{3}-\d{4}/
puts index  # 9

# sub() - Ersetzt erste Übereinstimmung
result = 'katze hund katze'.sub(/katze/, 'vogel')
puts result  # "vogel hund katze"

# gsub() - Ersetzt alle Übereinstimmungen
phone = '(+49) 151 123 4567'
cleaned = phone.gsub(/[^\d]/, '')
puts cleaned  # "491511234567"

# split() - Teilt nach Muster
csv = 'apfel,banane, orange , traube'
fruits = csv.split(/\s*,\s*/)
puts fruits  # ["apfel", "banane", "orange", "traube"]

Erfassungsgruppen

pattern = /(\d{4})-(\d{2})-(\d{2})/
match = '2025-01-17'.match(pattern)

if match
  puts match[0]  # "2025-01-17" (vollständige Übereinstimmung)
  puts match[1]  # "2025" (Gruppe 1)
  puts match[2]  # "01" (Gruppe 2)
  puts match[3]  # "17" (Gruppe 3)
end

Benannte Gruppen

pattern = /(?<jahr>\d{4})-(?<monat>\d{2})-(?<tag>\d{2})/
match = '2025-01-17'.match(pattern)

if match
  puts match[:jahr]   # "2025"
  puts match[:monat]  # "01"
  puts match[:tag]    # "17"
end

Ersetzen mit Blöcken

text = 'Ich habe 5 Äpfel und 10 Orangen'

result = text.gsub(/\d+/) { |num| (num.to_i * 2).to_s }
puts result  # "Ich habe 10 Äpfel und 20 Orangen"

# Mit benannten Gruppen
pattern = /(?<vorname>\w+)\s+(?<nachname>\w+)/
text = 'Hans Müller'

result = text.gsub(pattern) do |match|
  m = Regexp.last_match
  "#{m[:nachname].upcase}, #{m[:vorname]}"
end
puts result  # "MÜLLER, Hans"

Flags

# i - Case-insensitive
/hallo/i.match('HALLO')  # Findet

# m - Multiline (. findet Zeilenumbruch)
/a.b/m.match("a\nb")  # Findet

# x - Free-Spacing (ignoriert Leerzeichen)
pattern = /
  \d{3}     # Vorwahl
  -         # Trennzeichen
  \d{3}     # Zentrale
  -         # Trennzeichen
  \d{4}     # Nummer
/x

# o - Einmal kompilieren (Optimierung)
pattern = /\d+/o

Die Suchen-und-Ersetzen-Funktion von Visual Studio Code (Strg/Cmd+H) unterstützt Regex mit leistungsstarken Transformationsfähigkeiten. Dieser Abschnitt zeigt 28 praktische Beispiele, die Entwickler täglich verwenden.

Zugriff auf Suchen und Ersetzen

Tastenkürzel:

  • Suchen: Strg+F (Windows/Linux) / Cmd+F (Mac)
  • Ersetzen: Strg+H (Windows/Linux) / Cmd+H (Mac)
  • Regex aktivieren: Klicken Sie auf den .*-Button oder drücken Sie Alt+R

Tipps:

  • Verwenden Sie Strg+Enter (Cmd+Enter) um alles zu ersetzen
  • Vorschau der Übereinstimmungen vor dem Ersetzen (werden gelb hervorgehoben)
  • Verwenden Sie F3 / Shift+F3 um durch Übereinstimmungen zu navigieren

Groß-/Kleinschreibungs-Transformationen

VS Code unterstützt spezielle Ersetzungssequenzen für Groß-/Kleinschreibungsumwandlung:

Sequenz Effekt Beispiel
\l Kleinbuchstabe nächstes Zeichen \l
\u Großbuchstabe nächstes Zeichen \u
\L Kleinbuchstaben alle folgenden Zeichen \L
\U Großbuchstaben alle folgenden Zeichen \U
\E Beendet Groß-/Kleinschreibungs-Transformation \U\E

Beispiel 1: Ersten Buchstaben großschreiben

Suchen:

\b(\w)(\w*)

Ersetzen:

\u$1$2

Vorher:

hallo welt

Nachher:

Hallo Welt

Dieser Abschnitt bietet über 25 einsatzbereite Regex-Muster.

E-Mail-Validierung

^[\w.-]+@[\w.-]+\.[a-z]{2,}$

Telefonnummern (Deutschland)

^(\+?49)?[-.\s]?\(?([0-9]{2,5})\)?[-.\s]?([0-9]{3,10})$

Datum (ISO 8601)

^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$

URL

^https?://(?:www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b

IPv4-Adressen

^(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)$

Hex-Farben

^#?([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$

Starkes Passwort

^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$

Benutzername (3-16 Zeichen)

^[a-zA-Z0-9_-]{3,16}$

UUID v4

^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$

Und 15+ weitere Muster mit vollständiger Dokumentation!

Regex-Anwendungen aus der realen Welt in der Entwicklung.

Formularvalidierung

const validators = {
  email: /^[\w.-]+@[\w.-]+\.[a-z]{2,}$/i,
  phone: /^\(?\d{2,5}\)?[-.\s]?\d{3,10}$/
};

Datenextraktion

E-Mails aus Text extrahieren:

import re
emails = re.findall(r'[\w.-]+@[\w.-]+\.[a-z]{2,}', text)

Log-Parsing

pattern = r'(?P<ip>[\d.]+).+(?P<status>\d{3})'

Code-Refactoring

Alte API-Aufrufe in VS Code konvertieren:

Suchen: apiClient\.get\('([^']+)'\)
Ersetzen: fetch('$1').then(r => r.json())

Häufige Fehler

1. Vergessen Sonderzeichen zu maskieren

❌ Falsch: datei.txt
✅ Richtig: datei\.txt

2. Gierig vs. Nicht-gierig

❌ Gierig: <.*> findet gesamtes <div>text</div>
✅ Nicht-gierig: <.*?> findet <div> und </div> separat

3. Keine Anker verwenden

/\d{3}/ findet "123" in "abc123def"
/^\d{3}$/ findet nur genau "123"

Performance-Tipps

  1. Verwenden Sie spezifische Zeichenklassen statt .
  2. Ankern Sie Muster wenn möglich
  3. Vermeiden Sie verschachtelte Quantoren (katastrophales Backtracking)
  4. Verwenden Sie atomare Gruppen für Performance
  5. Kompilieren Sie Muster für Wiederverwendung

Debugging

  1. Testen Sie auf regex101.com
  2. Verwenden Sie Verbose-Modus mit Kommentaren
  3. Teilen Sie komplexe Muster in Teile
  4. Testen Sie Grenzfälle

Online-Tools

Regex-Tester

  • regex101.com - Bester Tester mit Erklärungen
  • regexr.com - Visueller Regex-Builder
  • regexpal.com - Einfacher, schneller Test

Visualisierer

  • debuggex.com - Railroad-Diagramme
  • regexper.com - Visuelles Tool

Lernressourcen

  • regexone.com - Interaktive Lektionen
  • regexlearn.com - Schritt-für-Schritt-Anleitung
  • regular-expressions.info - Dokumentation

IDE-Erweiterungen

  • Regex Previewer (VS Code)
  • Regex Tester (VS Code)

Zeichenklassen

Muster Findet
\d Ziffer [0-9]
\w Wortzeichen [a-zA-Z0-9_]
\s Leerzeichen
. Beliebiges Zeichen

Quantoren

Muster Bedeutung
* 0 oder mehr
+ 1 oder mehr
? 0 oder 1
{n} Genau n

Anker

Muster Bedeutung
^ Zeilenanfang
$ Zeilenende
\b Wortgrenze

Flags

Flag Bedeutung
i Case-insensitive
g Global
m Multiline
s Dotall

Allgemeine Fragen

F: Was ist der Unterschied zwischen gierigen und nicht-gierigen Quantoren?

A: Gierig findet so viel wie möglich. Nicht-gierig (*?, +?) findet so wenig wie möglich.

F: Wie finde ich einen literalen Punkt?

A: Maskieren Sie ihn mit Backslash: \.

F: Was ist katastrophales Backtracking?

A: Wenn die Regex viele Kombinationen versucht, was zu Langsamkeit führt. Vermeiden Sie verschachtelte Quantoren wie (a+)+.

F: Können Regex eine E-Mail perfekt validieren?

A: Nein. Verwenden Sie Regex für Basis-Format, dann verifizieren Sie per E-Mail.

F: Wie finde ich über mehrere Zeilen?

A: Verwenden Sie das s-Flag, oder verwenden Sie [\s\S]* statt .*.

VS Code-spezifisch

F: Wie ersetze ich mit Großbuchstaben in VS Code?

A: Verwenden Sie \u (nächstes großschreiben), \U (alles großschreiben).

F: Kann ich Regex in VS Code Dateisuche verwenden?

A: Ja! Drücken Sie Strg+Shift+F und aktivieren Sie Regex (Alt+R).

Chrome-Erweiterung Regex Data Extractor

Unser Regex Data Extractor hilft Ihnen, Daten von Webseiten mit den Mustern aus diesem Leitfaden zu extrahieren.

Hauptfunktionen

  • Musterbibliothek: Vorgefertigte Muster
  • Echtzeit-Test: Testen Sie Regex auf jeder Webseite
  • Multi-Format-Export: CSV, JSON, Excel, PDF
  • Batch-Extraktion: Extrahieren Sie von mehreren Seiten

Beispiel: E-Mails extrahieren

  1. Installieren Sie Regex Data Extractor
  2. Navigieren Sie zu einer Webseite
  3. Klicken Sie auf das Erweiterungssymbol
  4. Geben Sie Muster ein: [\w.-]+@[\w.-]+\.[a-z]{2,}
  5. Klicken Sie "Extrahieren"
  6. Exportieren Sie zu CSV/JSON

Beispiel: Preise extrahieren

Muster: €([0-9]{1,3}(?:\.?[0-9]{3})*,?[0-9]{2})
Findet: €1.234,56, €99,99

Profi-Tipps

  • Speichern Sie häufig verwendete Muster
  • Verwenden Sie benannte Gruppen für strukturierte Daten
  • Testen Sie Muster zuerst
  • Exportieren Sie für Datenanalyse

Holen Sie sich Regex Data Extractor →

regexreguläre ausdrückecheat sheetmustertutorialvs codepythonjavascriptphp

Last updated: 16. Januar 2025