Reguläre Ausdrücke (Regex) ermöglichen komplexe Mustersuche in Texten. Unverzichtbar für Log-Analyse, Konfiguration und Programmierung.

Grundlagen

Literale Zeichen

Einfache Zeichen matchen sich selbst:

server    → matcht "server"
error     → matcht "error"

Metazeichen

Diese Zeichen haben besondere Bedeutung:

| Zeichen | Bedeutung | |---------|-----------| | . | Ein beliebiges Zeichen | | * | 0 oder mehr Wiederholungen | | + | 1 oder mehr Wiederholungen | | ? | 0 oder 1 Wiederholung | | ^ | Zeilenanfang | | $ | Zeilenende | | \ | Escape-Zeichen |

Zeichenklassen

Vordefinierte Klassen

| Pattern | Bedeutung | Beispiel | |---------|-----------|----------| | \d | Ziffer (0-9) | \d+ → "123" | | \w | Wort-Zeichen | \w+ → "abc_123" | | \s | Whitespace | \s+ → " " | | \D | Keine Ziffer | \D+ → "abc" | | \W | Kein Wort-Zeichen | \W → "!" | | \S | Kein Whitespace | \S+ → "text" |

Eigene Klassen

[aeiou]     → Ein Vokal
[0-9]       → Eine Ziffer
[a-zA-Z]    → Ein Buchstabe
[^0-9]      → Keine Ziffer (negiert)

Quantoren

| Quantor | Bedeutung | Beispiel | |---------|-----------|----------| | | 0 oder mehr | a → "", "a", "aaa" | | + | 1 oder mehr | a+ → "a", "aaa" | | ? | 0 oder 1 | a? → "", "a" | | {3} | Genau 3 | a{3} → "aaa" | | {2,4} | 2 bis 4 | a{2,4} → "aa", "aaa" | | {2,} | 2 oder mehr | a{2,} → "aa", "aaaa" |

Anker

| Anker | Bedeutung | Beispiel | |-------|-----------|----------| | ^ | Zeilenanfang | ^Error → "Error..." | | $ | Zeilenende | error$ → "...error" | | \b | Wortgrenze | \bcat\b → "cat", nicht "catch" |

Gruppen

Capture Groups

(error|warning)    → "error" oder "warning"
(\d{4})-(\d{2})    → "2024-01" (zwei Gruppen)

Non-Capture Groups

(?:error|warning)  → Matcht, aber nicht erfasst

Backreferences

(\w+)\s+\1         → "word word" (Wiederholung)

Praktische Beispiele

E-Mail-Adresse

[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}

IP-Adresse (einfach)

\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}

IP-Adresse (genauer)

\b(?:(?: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]?)\b

Datum (YYYY-MM-DD)

\d{4}-\d{2}-\d{2}

URL

https?://[^\s]+

Telefonnummer (deutsch)

(?:\+49|0)[0-9\s/-]{8,}

Regex mit grep

Basis-Regex

grep 'error' /var/log/syslog

Extended Regex (-E)

grep -E 'error|warning' /var/log/syslog

Perl-Regex (-P)

grep -P '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}' access.log

Case-insensitive

grep -i 'error' /var/log/syslog

Nur Match ausgeben

grep -oE '\d+\.\d+\.\d+\.\d+' access.log

Regex in sed

Suchen und Ersetzen

# Einfach
sed 's/alt/neu/' datei.txt

# Global (alle Vorkommen)
sed 's/alt/neu/g' datei.txt

# Mit Regex
sed 's/[0-9]\+/NUMMER/g' datei.txt

Capture Groups

# Reihenfolge umdrehen
sed 's/\(\w\+\) \(\w\+\)/\2 \1/' datei.txt

# Extended
sed -E 's/(\w+) (\w+)/\2 \1/' datei.txt

Zeilen löschen

# Zeilen mit "DEBUG" löschen
sed '/DEBUG/d' logfile.txt

# Leerzeilen löschen
sed '/^$/d' datei.txt

Regex in awk

# Zeilen mit IP-Adressen
awk '/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/' access.log

# Feld extrahieren wenn Match
awk '/error/ {print $1, $2}' logfile.txt

Regex in Python

import re

text = "Server-IP: 192.168.1.100, Port: 8080"

# Match finden
match = re.search(r'\d+\.\d+\.\d+\.\d+', text)
if match:
    print(match.group())  # 192.168.1.100

# Alle Matches
numbers = re.findall(r'\d+', text)
print(numbers)  # ['192', '168', '1', '100', '8080']

# Ersetzen
new_text = re.sub(r'\d+\.\d+\.\d+\.\d+', 'X.X.X.X', text)

Log-Analyse Beispiele

Apache Access Log

# IP-Adressen extrahieren
grep -oE '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' access.log | sort | uniq -c | sort -rn

# 404-Fehler finden
grep -E ' 404 ' access.log

# Requests pro Stunde
grep -oE '\[[0-9]+/[A-Za-z]+/[0-9]+:[0-9]+' access.log | sort | uniq -c

Auth Log (SSH-Versuche)

# Fehlgeschlagene Logins
grep -E 'Failed password' /var/log/auth.log

# IPs extrahieren
grep -oE 'from [0-9.]+' /var/log/auth.log | sort | uniq -c | sort -rn

Syslog

# Fehler in letzter Stunde
grep -E "$(date '+%b %d %H')" /var/log/syslog | grep -i error

Lookahead und Lookbehind

Positive Lookahead (?=)

\d+(?= Euro)    → "100" in "100 Euro"

Negative Lookahead (?!)

\d+(?! Euro)    → Zahlen nicht gefolgt von "Euro"

Positive Lookbehind (?<=)

(?<=\$)\d+      → "100" in "$100"

Negative Lookbehind (?<!)

(?<!\$)\d+      → Zahlen ohne $ davor

Häufige Fehler

Zu gierig

.*              → Matcht alles (gierig)
.*?             → Minimal matchen (nicht-gierig)

Escape vergessen

\.              → Literal "."
\d+\.\d+        → "3.14"

Anker vergessen

^error$         → Nur "error"
error           → "error" irgendwo

Regex testen

Online-Tools

  • regex101.com (empfohlen)
  • regexr.com
  • regextester.com

Im Terminal

# Mit grep testen
echo "Test 123 Text" | grep -oE '\d+'

# Mit Perl
echo "Test 123 Text" | perl -ne 'print "$1\n" if /(\d+)/'

Cheatsheet

.       Ein beliebiges Zeichen
\d      Ziffer [0-9]
\w      Wort-Zeichen [a-zA-Z0-9_]
\s      Whitespace
^       Zeilenanfang
$       Zeilenende
*       0 oder mehr
+       1 oder mehr
?       0 oder 1
{n}     Genau n
{n,m}   n bis m
[abc]   Einer von a, b, c
[^abc]  Keiner von a, b, c
(...)   Gruppe
|       Oder
\b      Wortgrenze

Fazit

Reguläre Ausdrücke sind anfangs komplex, aber extrem nützlich. Starten Sie mit einfachen Patterns und nutzen Sie regex101.com zum Testen. Mit etwas Übung werden Regex zu einem unverzichtbaren Werkzeug.