Reguläre Ausdrücke (kurz: Regex, RegExp) sind eine kompakte Sprache, mit der sich Text-Muster beschreiben lassen — von einfachen Wortsuchen bis zu komplexen Substitutionen. In der GLAM- und DH-Praxis tauchen sie überall auf, wo grosse Mengen Text inspiziert oder umgeformt werden: Fehlersuche in OCR-Output, Massen-Korrektur in TEI-Dateien, Datums-Normalisierung, Validierung von Erschliessungs-Feldern.

Regex ist nicht eine Sprache, sondern eine Familie mit kleinen Dialekt-Unterschieden. Die wichtigsten Varianten in der Praxis:

VarianteWo
POSIX Basic (BRE)grep ohne Optionen, sed
POSIX Extended (ERE)grep -E, egrep, awk
PCRE (Perl-Compatible)grep -P, ripgrep (rg), ack, viele Editoren
JavaScriptVisual Studio Code, Browser
ICULibreOffice
Word-WildcardsMS Word — kein echtes Regex

In der Praxis am häufigsten: PCRE-ähnliche Syntax, mit kleinen Stolpersteinen beim Wechsel zwischen Tools.

Grundbausteine

TokenBedeutung
.beliebiges Zeichen (ausser Newline)
\d \w \sZiffer · Wort-Zeichen · Whitespace
\D \W \Sjeweils das Negativ
[abc]eine der Optionen
[a-z]Bereich
[^abc]nicht eines davon
^ $Zeilen-/String-Anfang/Ende
\bWortgrenze
* + ?0+ · 1+ · 0 oder 1 (greedy)
*? +? ??dasselbe lazy (so wenig wie möglich)
{n} {n,m}exakt n · n bis m
(...)Capture-Gruppe
(?:...)Non-Capture-Gruppe
(?<name>...)Named-Capture (PCRE/JS)
\1 \2 $1 $2Backreferenz auf Capture-Gruppe
`ab`
(?=...) (?!...)Lookahead positiv / negativ
(?<=...) (?<!...)Lookbehind positiv / negativ

Beispiele aus dem GLAM-Alltag

# Schweizer Datum DD.MM.YYYY
\b\d{1,2}\.\d{1,2}\.\d{4}\b

# ISO-Datum YYYY-MM-DD
\b\d{4}-\d{2}-\d{2}\b

# E-Mail (vereinfacht)
\b[\w._%+-]+@[\w.-]+\.[A-Za-z]{2,}\b

# DOI
\b10\.\d{4,9}/[-._;()/:A-Za-z0-9]+\b

# GND-ID-Pattern (ohne Bindestrich-Variante)
\b\d{6,9}\b

# TEI-Tag (start oder end) für Personen
</?persName[^>]*>

# Mehrere Leerzeichen
\s{2,}

# „seit/bis-Datierung" mit zwei Jahreszahlen
(\d{4})[\s\-–]+(\d{4})

# Whitespace am Zeilenanfang
^\s+

# Eine Zeile, die nicht mit Doppelpunkt endet
^(?!.*:\s*$).*\S$

In grep / ack / ripgrep

grep ist auf jedem Unix-System; ripgrep (rg) ist heute der pragmatische Standard für Code- und Textsuche, ack der ältere Verwandte. Alle drei können Regex; ripgrep und ack sind defaultmässig PCRE-nah, grep nutzt BRE und braucht -E oder -P für mehr.

# Einfache Suche
grep -E '\b\d{4}-\d{2}-\d{2}\b' datei.txt
rg '\b\d{4}-\d{2}-\d{2}\b' .

# Case-insensitive, mit Zeilennummern, Kontext
grep -niE '...' datei.txt
rg -in '...' .

# Nur Dateinamen mit Treffer
grep -lE '...' *.xml
rg -l '...' .

# Zeilen, die NICHT matchen
grep -vE '^#' config.ini

# Nur die Treffer (statt der ganzen Zeile)
grep -oE '\b10\.\d{4,9}/\S+\b' *.bib

# Über Verzeichnisse, mit Glob-Filter
grep -rE 'persName' --include='*.xml' .
rg 'persName' -g '*.xml'

# Multiline (PCRE-Modus, mit -P bzw. -U)
grep -Pzo '(?s)<persName>.*?</persName>' datei.xml
rg -U --multiline 'persName>[\s\S]*?</persName' .

# Suchen + Ersetzen (sed; macOS und GNU unterscheiden sich beim -i-Backup)
sed -E 's/\b(\d{4})-(\d{2})-(\d{2})\b/\3.\2.\1/g' datei.txt

ripgrep ist bei grossen Datenmengen typisch um eine Grössenordnung schneller als grep, respektiert .gitignore automatisch und hat saubere Defaults — Empfehlung für die Code-/Daten-Recherche im Alltag.

In Visual Studio Code

VS Code hat Regex direkt im Find/Replace-Dialog (Cmd-F für Find, Cmd-Alt-F für Find/Replace, oder im Search-Panel mit Cmd-Shift-F für Workspace-weite Suche). Den Regex-Modus einschalten mit dem .*-Knopf rechts neben dem Eingabefeld (oder Alt-R).

# Find:
<persName ref="(\w+)">

# Replace (in $-Notation):
<persName ref="https://d-nb.info/gnd/$1">
# Find: Datums-Format ändern
\b(\d{1,2})\.(\d{1,2})\.(\d{4})\b

# Replace: ISO-Datum mit Padding
$3-$2-$1
# Find: leere TEI-Tags entfernen
<(\w+)\s*>\s*</\1>

# Replace: (leer)

Wichtig in VS Code:

  • Capture-Backrefs in Replace mit $1, $2, …, nicht \1 (einzige Ausnahme: \n für Newline ist erlaubt).
  • Multiline-Suche im Find-Feld mit \n für Zeilenumbrüche.
  • Case-Modifier: \U$1 (uppercase), \L$1 (lowercase), \u$1 (nur erstes Zeichen) im Replace.
  • Suche pro Datei mit dem Lupen-Icon links; Workspace-weit mit der Such-Sidebar (dort auch Glob-Includes/-Excludes).
  • Preview der Änderungen vor dem Apply — Pflicht für grosse Sweeps.

VS-Code-Regex ist im Wesentlichen der JavaScript-Dialekt: \d, \w, \s, Lookahead/Lookbehind, named captures (?<name>...), aber kein \K und keine rekursiven Pattern.

In MS Word und LibreOffice

Hier ist Vorsicht geboten — die beiden Programme implementieren völlig unterschiedliche Pattern-Sprachen:

Word (Windows/Mac) — „Wildcards”

Word hat kein echtes Regex. Das Feature heisst „Wildcards” (engl.) bzw. „Platzhalter verwenden” (de) und muss im Suchen-Dialog (Cmd-F → erweiterte Optionen → „Mit Platzhaltern suchen”) explizit aktiviert werden. Eine eigene, beschränkte Syntax:

Word-WildcardBedeutung
?beliebiges Zeichen
*beliebige Zeichenfolge
[abc]eine der Optionen
[a-z]Bereich
[!abc]Negation
< >Wortanfang / -ende (statt \b)
@ein oder mehr des vorherigen (statt +)
{n} {n,} {n,m}Wiederholung
(...)Gruppe
\1 \2Backreferenz im Ersetzen

Beispiele Word:

Suchen:    (<*>) (<*>)
Ersetzen:  \2 \1
# vertauscht zwei Wörter

Suchen:    [0-9]{1,2}\.[0-9]{1,2}\.[0-9]{4}
# findet Datum DD.MM.YYYY (ohne Capture)

Suchen:    <persName>(*)</persName>
Ersetzen:  \1
# entfernt Tag, behält Inhalt

Wichtige Word-Spezifika: \d und \w existieren nicht. Punkt . matcht den Punkt, nicht ein beliebiges Zeichen. Anker ^ und $ haben andere Bedeutung (^p = Absatzmarke, ^t = Tab). Die Quirks der Word-Syntax sind die häufigste Stolperfalle, wenn man von echten Regex herkommt.

LibreOffice — ICU-Regex

LibreOffice (Writer und Calc) nutzt echtes Regex auf Basis der ICU-Library — sehr nah an PCRE. Im Suchen-Dialog (Cmd-Alt-F) den Haken bei „Reguläre Ausdrücke” setzen.

# Datum DD.MM.YYYY → YYYY-MM-DD
Suchen:    \b(\d{1,2})\.(\d{1,2})\.(\d{4})\b
Ersetzen:  $3-$2-$1

# Mehrere Leerzeichen zu einem
Suchen:    \s{2,}
Ersetzen:  (ein Leerzeichen)

# Absatz-Ende-Marker (nur in Replace) als \n
# In ICU: \n in Replace = Zeilenumbruch

Wichtige LibreOffice-Spezifika:

  • Backreference im Ersetzen mit $1, nicht \1.
  • Newline im Suchfeld ist \n, in Calc auch \n zwischen Spalten — Vorsicht, Calc und Writer unterscheiden sich subtil.
  • Lookbehind funktioniert (ICU >= 70), war früher eingeschränkt.

Dialekt-Unterschiede in der Übersicht

Featuregrep BREgrep ERE / ack / rgVS CodeLibreOfficeWord
+ ? {}mit \+ etc.direktdirektdirekt@ für +, {}
\d \w \sneinmit -P jajajanein
Lookaroundneinmit -P jajaja (modern)nein
Named Captureneinmit -P jajajanein
Capture-Backref im Replace\1\1$1$1\1
Multiline-Defaultneinneinneinneinim Wildcards-Modus eingeschränkt
Punkt matcht Newlineneinneinmit (?s) flagmit (?s) flag(irrelevant)

Häufige Fallen

  • Greedy by default<.*> matcht in <a>x</a> die ganze Zeile von <a bis </a>. Lazy mit <.*?> oder Negation <[^>]*> nutzen.
  • Punkt im Datums-Pattern\d{1,2}.\d{1,2}.\d{4} matcht auch 12345678 (Punkte als „beliebig”). Backslash-escape: \.
  • Anker-Bedeutung verwechselt — in Word ist ^p Absatz, in den meisten anderen Tools ist ^ „Zeilenanfang”.
  • Backref-Notation falsch — in sed/grep -P mit \1, in VS Code/LibreOffice mit $1. Kopier-und-paste zwischen Tools sorgt regelmässig für Frust.
  • Encoding — Regex auf Latin-1-Datei kann mit \w Umlaute nicht matchen; UTF-8 + Unicode-Flag (-u in ripgrep) löst es.
  • Multiline-Verhalten — defaultmässig matcht . keinen Newline. (?s)-Flag oder explizit [\s\S] als „wirklich alles”.
  • Catastrophic Backtracking — verschachtelte unbeschränkte Quantifizierer ((a+)+b) können bei Grossdateien minutenlang hängen. Im Zweifel possessiv ((a++)+b in PCRE) oder Pattern umschreiben.
  • Vor dem produktiven Replace immer „Find only” — eine schlecht formulierte Regex zerstört in Sekunden Hunderte Dateien.
  • Word-Wildcards sind nicht Regex — wer \d in Word eingibt, sucht nach dem Backslash gefolgt von „d”.

Werkzeuge zum Üben und Debuggen

  • regex101.com — interaktiver Tester mit Erklärung jedes Tokens, Flavor-Auswahl (PCRE, JS, .NET, Python, Go, Java)
  • regexr.com — alternativer Tester mit Cheat-Sheet
  • VS Code „Regex Preview”-Extension — zeigt Treffer im Editor live
  • pcregrep / pcre2grep — wenn grep -P im System fehlt
  • ripgrep --debug — zeigt, wie das Pattern intern interpretiert wird

Lektüre-Empfehlung

Jeffrey E. F. Friedl, Mastering Regular Expressions (3. Aufl., O’Reilly 2006). Die kanonische Referenz. Friedl erklärt nicht nur die Syntax, sondern auch wie die Engine intern arbeitet — Backtracking, NFA vs. DFA, Performance-Eigenschaften. Wer regelmässig Regex auf grossen Texten betreibt, spart sich nach diesem Buch viele „warum braucht das jetzt zehn Sekunden”-Momente. Pflichtlektüre für alle, die über Copy-und-Paste hinaus arbeiten wollen.

Verhältnis zu anderen Werkzeugen

  • Pandoc — kann via Lua-Filter Regex-Substitutionen während der Konversion machen
  • Gitgit grep nutzt POSIX BRE, mit -E ERE oder -P PCRE
  • OpenRefine — GREL-Funktionen wie replace(value, /regex/, "...") mit JS-Regex-Syntax
  • xmlstarlet — kombiniert mit Regex für XML-Massen-Edit (kombinieren mit XPath)