JavaScript: Reguläre Ausdrücke
Reguläre Ausdrücke sind Sequenzen von Zeichen, die in symbolischer Form Suchmuster bzw. Filterregeln für Zeichenketten (Strings) beschreiben und in diversen Programmiersprachen und Textverarbeitungsprogrammen verwendet werden. Die Syntax und Bedeutung der verwendeten Metazeichen kann sich je nach Implementierung unterscheiden, daher beziehen sich die Angaben auf dieser Seite nur auf die Implementierung in JavaScript.
Reguläre Ausdrücke werden grundsätzlich als Literal ohne Anführungszeichen geschrieben. Stattdessen werden sie am Anfang und am Ende mit einem Slash / begrenzt. Möchte man einen regulären Ausdruck aus einem String erzeugen, kann man dazu ein entsprechendes RegExp-Objekt erzeugen.
Ein regulärer Ausdruck kann um bestimmte Modifikatoren (flags) ergänzt werden:
g (global), wenn die Suche nach dem ersten Fund fortgesetzt werden soll,
i (insensitive) für die Nicht-Unterscheidung von Groß- und Kleinschreibung,
m (multiline), wenn ein mehrzeiliger String durchsucht werden soll, oder
u (unicode), wenn die Eingabe als Sequenz von Unicode-Zeichen verarbeitet werden soll.
Alle Zeichen, die selbst keine Metazeichen sind und nicht durch Metazeichen geregelt sind, stehen für sich selbst. Die Bedeutung eines Metazeichens kann durch den Backslash \ aufgehoben werden.
Hier ein Beispiel für die Verwendung eines regulären Ausdrucks für die Suche nach katze mit der Methode match() (s. auch MDN).
sample = "Die Katze tritt die Treppe krumm.";
find = sample.match(/katze/gi);
console.log(find); // ["Katze"]
// dies entspricht:
regex = new RegExp("katze", "gi");
find = sample.match(regex);
console.log(find); // ["Katze"]
Metazeichen .
Der Punkt . steht für ein beliebiges Zeichen (außer \n, \r, \u2028 und \u2029).
d.e | Ein beliebiges Zeichen zwischen d und e. |
sample = "Deine Katze tritt die Treppe krumm.";
find = sample.match(/e.t/gi);
console.log(find); // (2) ["e t", "e T"]
Metazeichen […]
In eckigen Klammern werden gesuchte Zeichen oder Zeichengruppen notiert. Ein Zirkumflex ^ als erstes Zeichen innerhalb von eckigen Klammern zeigt die Negation der folgenden Zeichen/-gruppen an – also alle Zeichen, die nicht zu diesen gehören.
Innerhalb eckiger Klammern finden einfache Metazeichen keine Anwendung, das heißt + etc. steht für sich selbst und muss nicht mit \ escapet werden. Escape-Sequenzen, die einem Zeichen oder einer Zeichenklasse entsprechen, wie \t oder \w, behalten allerdings ihre Bedeutung.
[abmnpq] | Eines der enthaltenen Zeichen soll gefunden werden. |
[a-z] | Ein Zeichen zwischen a und z soll gefunden werden. |
[^a-z] | Ein Zeichen außerhalb von a und z soll gefunden werden. |
[a-z0-9] | Ein Zeichen zwischen a und z sowie zwischen 0 und 9 soll gefunden werden. |
[-a-z] oder [a-z-] | Ein Zeichen zwischen a und z sowie das Minuszeichen - soll gefunden werden. |
sample = "Die Katze tritt die Treppe krumm.";
find = sample.match(/[A-E]/gi);
console.log(find); // (8) ["D", "e", "a", "e", "d", "e", "e", "e"]
sample = "Die Katze tritt die Treppe krumm.";
find = sample.match(/[^A-E]/gi);
console.log(find); // (25) ["i", " ", "K", "t", "z", " ", "t", "r", "i", "t", "t", " ", "i", " ", "T", "r", "p", "p", " ", "k", "r", "u", "m", "m", "."]
Metazeichen {…}
In geschweiften Klammern werden Unter- und Obergrenzen für die Anzahl der zusammenhängenden Zeichen notiert.
d{5} | Genau 5 Zeichen d in Folge sollen gefunden werden. |
d{2,4} | 2 bis 4 Zeichen d in Folge sollen gefunden werden. |
d{3,} | Mindestens 3 Zeichen d in Folge sollen gefunden werden. |
d{0,3} | Keine oder höchstens 3 Zeichen d in Folge sollen gefunden werden. |
sample = "xxiiixxiiiiiixxii.";
find = sample.match(/i{1,3}/gi);
console.log(find); // (4) ["iii", "iii", "iii", "ii"]
Metazeichen (…)
In runden Klammern werden Zeichen zusammengefasst, auf die beispielsweise gemeinsam ein Metazeichen angewendet werden soll. Es kann dabei festgelegt werden, ob diese Zeichen gespeichert werden sollen, oder um zu prüfen, ob eine bestimmte andere Zeichensequenz nachfolgt.
(foo) | foo wird gesucht und gespeichert. |
(?:foo) | foo wird gesucht und nicht gespeichert. |
foo(?=bar) | Übereinstimmung, wenn foo vor bar steht. |
foo(?!bar) | Übereinstimmung, wenn foo nicht vor bar steht. |
(?<=bar)foo | Übereinstimmung, wenn foo auf bar folgt. |
(?<!bar)foo | Übereinstimmung, wenn foo nicht auf bar folgt. |
Ein gespeichertes Zeichen kann durch \ gefolgt vom Index der Speicherung (beginnend mit 1) wieder eingefügt werden. Zur Verwendung von gespeicherten Zeichenfolgen siehe MDN.
sample = "foofoofoo";
find = sample.match(/(foo)+/gi); // + bezieht sich auf foo
console.log(find); // ["foofoofoo"]
find = sample.match(/foo+/gi); // + bezieht sich auf o nach fo
console.log(find); // (3) ["foo", "foo", "foo"]
sample = "Katzenklo und Katzenfutter";
find = sample.match(/katzen(?=klo)\w+/gi);
console.log(find); // ["Katzenklo"]
find = sample.match(/katzen(?!klo)\w+/gi);
console.log(find); // ["Katzenfutter"]
sample = "Hund, Katze, Maus, Käse";
find = sample.match(/Hund(,)\sKatze\1/gi); // Beispiel einer Speicherung und Einsetzung durch \1
console.log(find); // ["Hund, Katze,"]
Metazeichen *
Der Asterisk * markiert Zeichen, die vorkommen dürfen aber nicht müssen.
d* | Der Buchstabe d darf vorkommen, muss es aber nicht. Entspricht {0,}. |
sample = "Deine Katze tritt die Treppe krumm.";
find = sample.match(/di*e/gi);
console.log(find); // (2) ["De", "die"]
Metazeichen +
Das Pluszeichen + markiert Zeichen, die mindestens einmal vorkommen.
d+ | Der Buchstabe d muss mindestens einmal vorkommen. Entspricht {1,}. |
sample = "Deine Katze tritt die Treppe krumm.";
find = sample.match(/f+/gi);
console.log(find); // null
Metazeichen ?
Das Fragezeichen ? markiert Zeichen, die maximal einmal vorkommen, aber nicht vorkommen müssen. Über die Verwendung von ? innerhalb von runden Klammern siehe dort.
d? | Der Buchstabe d darf maximal einmal vorkommen, muss es aber nicht. Entspricht {0,1}. |
sample = "Deine Katze tritt die Treppe krumm.";
find = sample.match(/ep?e/gi);
console.log(find); // null
find = sample.match(/di?e/gi);
console.log(find); // (2) ["De", "die"]
Wird das ? direkt nach einem der Quantoren *, +, ? oder {} notiert, deaktiviert es dessen Gierigkeit (greedyness) und macht ihn genügsam (non-greedy). Das bedeutet, dass eine Übereinstimmung bereits bei der geringsten möglichen Zahl von Zeichen festgestellt wird.
sample = "Tor! Toor! Tooooor!";
find = sample.match(/.o+/gi);
console.log(find); // (3) ["To", "Too", "Tooooo"]
find = sample.match(/.o+?/gi);
console.log(find); // (5) ["To", "To", "To", "oo", "oo"]
Metazeichen |
Der senkrechte Trennstrich | trennt Zeichenfolgen, die entweder oder vorkommen müssen.
foo|bar | Die Zeichenfolge foo oder die Zeichenfolge bar muss vorkommen. |
sample = "Deine Katze tritt die Treppe krumm.";
find = sample.match(/it|pe/gi);
console.log(find); // (2) ["it", "pe"]
Metazeichen ^
Der Zirkumflex ^ markiert Zeichenfolgen, die am Anfang des zu analysierenden Strings (bzw. am Anfang einer Zeile, wenn der Modifikator m gesetzt ist) vorhanden sein müssen. Über die Verwendung von ^ innerhalb von eckigen Klammern siehe dort.
^foo | Die Zeichenfolge foo muss am Anfang des Strings bzw. einer Zeile vorhanden sein. |
sample = "Deine Katze tritt die Treppe krumm.";
find = sample.match(/^katze/gi);
console.log(find); // null
find = sample.match(/^deine/gi);
console.log(find); // ["Deine"]
Metazeichen $
Das Dollarzeichen $ markiert Zeichenfolgen, die am Ende des zu analysierenden Strings (bzw. am Ende einer Zeile, wenn der Modifikator m gesetzt ist) vorhanden sein müssen.
foo$ | Die Zeichenfolge foo muss am Ende des Strings bzw. einer Zeile vorhanden sein. |
sample = "Deine Katze tritt die Treppe krumm.";
find = sample.match(/krumm$/gi);
console.log(find); // null
find = sample.match(/krumm\.$/gi);
console.log(find); // ["krumm."]
find = sample.match(/^deine|krumm\.$/gi);
console.log(find); // (2) ["Deine", "krumm."]
Escapezeichen \
Der Backslash \ bewirkt für alle oben genannten Metazeichen (einschließlich /, der sonst als Grenze des regulären Ausdrucks verstanden wird), dass diese ihre funktionale Bedeutung verlieren und als normale Zeichen betrachtet werden.
Wird er bestimmten Buchstaben vorangestellt, so repräsentieren diese Kombinationen bestimmte Bestandteile einer Zeichenkette, die weiter unten im Einzelnen beschrieben werden.
Der Backslash muss selbst mit \ markiert werden, wenn er für sich selbst stehen soll.
Innerhalb von runden Klammern kann mit dem Backslash gefolgt von einer Zahl ein gespeichertes Zeichen wieder eingefügt werden.
sample = "Deine Ka+tze tritt + die Treppe krumm.";
find = sample.match(/.\+./gi);
console.log(find); // (2) ["a+t", " + "]
sample = "Die Katze tritt\\die Treppe krumm.";
find = sample.match(/.\\./gi);
console.log(find); // ["t\d"]
Metazeichen \w und \W
Das Metazeichen \w steht für ein Wortzeichen, was alle kleinen und großen Buchstaben, Ziffern und den Unterstrich einschließt. Es ist daher gleichbedeutend mit [A-Za-z0-9_]. Umlaute und andere buchstabenähnliche Zeichen zählen nicht dazu!
Das Zeichen \W repräsentiert die Negation, also [^A-Za-z0-9_].
sample = "a;b-c#d&e%f§";
find = sample.match(/\w/gi);
console.log(find); // (6) ["a", "b", "c", "d", "e", "f"]
find = sample.match(/\W/gi);
console.log(find); // (6) [";", "-", "#", "&", "%", "§"]
sample = "Schöne Grüße!";
find = sample.match(/\w/gi);
console.log(find); // (8) ["S", "c", "h", "n", "e", "G", "r", "e"]
Metazeichen \d und \D
Das Metazeichen \d steht für alle westlichen (‚arabischen‘) Ziffern. Es ist daher gleichbedeutend mit [0-9].
Das Zeichen \D repräsentiert die Negation, also [^0-9].
sample = "a9b8c7d6e5f4";
find = sample.match(/\d/gi);
console.log(find); // (6) ["9", "8", "7", "6", "5", "4"]
find = sample.match(/\D/gi);
console.log(find); // (6) ["a", "b", "c", "d", "e", "f"]
Metazeichen \s und \S
Das Metazeichen \s steht für eine Gruppe von Steuer- und Whitespace-Zeichen:
\u0009 – Tabulator
\u000A – Zeilenvorschub
\u000B – vertikaler Tabulator
\u000C – Seitenvorschub
\u000D – Wagenrücklauf
\u0020 – Leerzeichen
\u00A0 – NO-BREAK SPACE
\u1680 – OGHAM SPACE MARK
\u2000 – EN QUAD
\u2001 – EM QUAD
\u2002 – EN SPACE
\u2003 – EM SPACE
\u2004 – THREE-PER-EM SPACE
\u2005 – FOUR-PER-EM SPACE
\u2006 – SIX-PER-EM SPACE
\u2007 – FIGURE SPACE
\u2008 – PUNCTUATION SPACE
\u2009 – THIN SPACE
\u200a – HAIR SPACE
\u2028 – LINE SEPARATOR
\u2029 – PARAGRAPH SEPARATOR
\u202f – NARROW NO-BREAK SPACE
\u205f – MEDIUM MATHEMATICAL SPACE
\u3000 – IDEOGRAPHIC SPACE
\ufeff – ZERO WIDTH NO-BREAK SPACE
Das Zeichen \S repräsentiert die Negation dieser Zeichen.
sample = "Die Katze tritt\tdie Treppe krumm.";
find = sample.match(/.\s./gi);
console.log(find); // (5) ["e K", "e t", "t d", "e T", "e k"]
Metazeichen \b und \B
Das Metazeichen \b steht für eine Wortgrenze, also den Raum vor dem ersten bzw. nach dem letzten Zeichen eines Wortes. Dieser Raum ist kein Zeichen und hat daher auch keine Länge. Ein Wort ist eine Folge von Wortzeichen, also alle Zeichen, die in \w enthalten sind.
Das Zeichen \B gibt an, dass keine Wortgrenze vorangeht bzw. folgt.
Innerhalb von eckigen Klammern steht \b für den Backspace (\x08 bzw. \cH).
sample = "Die Katze tritt die Treppe krumm.";
find = sample.match(/.e\b/gi); // ein beliebiges Zeichen, gefolgt von e, gefolgt von einer Wortgrenze
console.log(find); // (4) ["ie", "ze", "ie", "pe"]
find = sample.match(/\Bt./gi); // ein t, das nicht auf eine Wortgrenze folgt, gefolgt von einem beliebeigen Zeichen
console.log(find); // (2) ["tz", "tt"]
Metazeichen \p und \P
Das Metazeichen \p repräsentiert ein Zeichen, das einer bestimmten Unicode-Eigenschaft entspricht, wobei zwischen binären und nicht-binären Eigenschaften unterschieden wird. Um den zu analysierenden String als Sequenz von Unicode-Zeichen zu verarbeiten, muss dazu der Modifikator u gesetzt werden. Siehe auch MDN.
Alle Unicode-Zeichen sind je nach Eigenschaft bestimmten Namens-Kategorien (UnicodePropertyName) zugeordnet, die wiederum in verschiedene Werte-Kategorien (UnicodePropertyValue) unterteilt sind. Gewöhnliche Buchstaben gehören beispielsweise in die Werte-Kategorie Letter der Namens-Kategorie General_Category.
Um in einem regulären Ausdruck eine Unicode-Eigenschaft anzugeben, kann die benötigte Werte-Kategorie allein oder explizit in Kombination mit der Namens-Kategorie angegeben werden. Ebenso ist die Angabe der Abkürzung einer Kategorie möglich.
Möchte man mehrere Eigenschaften kombinieren, kann man diese durch | getrennt notieren.
\p{Letter} | UnicodePropertyValue |
\p{L} | UnicodePropertyValue (abgekürzt) |
\p{General_Category=Letter} | UnicodePropertyName=UnicodePropertyValue |
\p{gc=L} | UnicodePropertyName=UnicodePropertyValue (abgekürzt) |
\p{Lu}|\p{Ll}|\p{Lt}|\p{Lm}|\p{Lo} | Mehrere alternative UnicodePropertyValues |
\p{Emoji_Presentation} | UnicodeBinaryPropertyName |
Das Zeichen \P repräsentiert die Negation dieser Zeichen.
sample = "Schöne Grüße!";
find = sample.match(/\w/gi);
console.log(find); // (8) ["S", "c", "h", "n", "e", "G", "r", "e"]
find = sample.match(/\p{General_Category=Letter}/gu);
console.log(find); // (11) ["S", "c", "h", "ö", "n", "e", "G", "r", "ü", "ß", "e"]
Metazeichen \x und \u
Mit den Metazeichen \x und \u können Unicode-Zeichen kodiert werden. Während \x Zeichen im zweistelligen hexadezimalen Bereich von 00 bis FF repräsentieren kann, ist dies mit \u im vierstelligen Bereich von 0000 bis FFFF möglich.
sample = "Schöne Grüße!";
find = sample.match(/.\xFC\u00DF./gi);
console.log(find); // ["rüße"]
Metazeichen \0, \f, \n, \r, \t und \v
Diese Metazeichen stehen für verschiedene Steuerzeichen:
\0 – NULL-Zeichen, entspricht \x00
\f – Seitenvorschub, entspricht \x0C und \cL
\n – Zeilenvorschub, entspricht \x0A und \cJ
\r – Wagenrücklauf, entspricht \x0D und \cM
\t – Tabulator, entspricht \x09 und \cI
\v – vertikaler Tabulator, entspricht \x0B und \cK
sample = "Die Katze tritt\x09die Treppe krumm.";
find = sample.match(/.\t./gi);
console.log(find); // ["t d"]
Metazeichen \c
Mit dem Metazeichen \c können Steuerzeichen im Ctrl-Schema (caret notation) im Bereich von A bis Z markiert werden.
\cA | Das Steuerzeichen ^A, entspricht \x01. |
\cB | Das Steuerzeichen ^B, entspricht \x02. |
\cC | Das Steuerzeichen ^C, entspricht \x03. |
… | … |
\cZ | Das Steuerzeichen ^Z, entspricht \x1A. |
sample = "Die Katze tritt\tdie Treppe krumm.";
find = sample.match(/.\cI./gi);
console.log(find); // ["t d"]