Java Regex-Syntax
Java Regex-Syntax — Zeichen, Klassen, Anker, Quantoren und spezielle Konstrukte im Überblick.
Ein regulärer Ausdruck ist eine kleine Mustersprache zur Beschreibung von Text. Java implementiert sie im Paket java.util.regex, und die Syntax ist der Perl-Stil-Dialekt, den die meisten modernen Sprachen teilen — mit einer Java-spezifischen Besonderheit: Jeder Backslash in einem Muster muss in einem Java-String-Literal verdoppelt werden, weil der Compiler ihn verbraucht, bevor die Regex-Engine ihn überhaupt sieht. Dieses Kapitel ist eine Referenz zu dieser Syntax: die Bausteine, die Sie kombinieren, um Text zu suchen, abzugleichen und zu validieren.
Wenn Sie neu bei regulären Ausdrücken in Java sind, beginnen Sie mit der Java Regex Einführung und kommen Sie dann hierher zurück, wenn Sie das vollständige Syntax-Cheat-Sheet benötigen.
Literale und Metazeichen
Die meisten Zeichen in einem Muster stimmen mit sich selbst überein: cat stimmt mit den drei Buchstaben c, a, t überein. Die Stärke liegt in den Metazeichen — Zeichen mit besonderer Bedeutung, die Sie zu Regeln kombinieren. Die zwölf Zeichen, die die Engine besonders behandelt, sind:
. ^ $ * + ? ( ) [ ] { } | \Um eines dieser Zeichen wörtlich abzugleichen, escapen Sie es mit einem Backslash. Denken Sie an die Doppelbackslash-Regel für Java-Quellcode: ein Regex \. wird im Code als "\\." geschrieben.
Pattern.matches("a.c", "abc"); // true — '.' matches any char
Pattern.matches("a.c", "a.c"); // true — '.' also matches a literal dot
Pattern.matches("a\\.c", "abc"); // false — '\.' matches ONLY a literal dot
Pattern.matches("a\\.c", "a.c"); // trueZeichenklassen
Eine Zeichenklasse in eckigen Klammern stimmt mit einem beliebigen einzelnen Zeichen aus einer Menge überein. Bereiche verwenden einen Bindestrich, und ein führendes ^ negiert die Menge.
"[aeiou]" // any one lowercase vowel
"[a-z]" // any one lowercase letter
"[A-Za-z0-9]" // any letter or digit
"[^0-9]" // any character that is NOT a digitJava bietet außerdem vordefinierte Klassen als Kurzschreibweise. Diese sind die, die Sie ständig verwenden:
| Kurzschreibweise | Äquivalent | Stimmt überein mit |
|---|---|---|
. | — | Beliebiges Zeichen außer einem Zeilenabschlusszeichen |
\d | [0-9] | Eine Ziffer |
\D | [^0-9] | Keine Ziffer |
\w | [a-zA-Z0-9_] | Ein Wortzeichen |
\W | [^a-zA-Z0-9_] | Kein Wortzeichen |
\s | [ \t\n\x0B\f\r] | Ein Leerzeichen |
\S | [^\s] | Kein Leerzeichen |
Die Großbuchstabenform ist immer die Negation der Kleinbuchstabenform. Siehe Java Regex Zeichenklassen für den vollständigen Satz, einschließlich POSIX- und Unicode-Klassen.
Quantoren: gierig, zögerlich, possessiv
Ein Quantor gibt an, wie oft das vorhergehende Element wiederholt werden darf. Standardmäßig sind Quantoren gierig — sie greifen so viel wie möglich und geben dann nach, wenn der Rest des Musters es erfordert. Fügen Sie ? hinzu, um einen Quantor zögerlich (so wenig wie möglich treffen) zu machen, oder +, um ihn possessiv (greifen und nie zurückgeben) zu machen.
| Quantor | Bedeutung |
|---|---|
* | Null oder mehr |
+ | Eins oder mehr |
? | Null oder eins (optional) |
{n} | Genau n |
{n,} | Mindestens n |
{n,m} | Zwischen n und m |
"\\d{3}" // exactly three digits
"\\d{2,4}" // two to four digits
"a+" // one or more 'a'
"colou?r" // matches "color" and "colour"
"<.+>" // greedy: on "<a><b>" matches the whole "<a><b>"
"<.+?>" // reluctant: on "<a><b>" matches just "<a>"Für einen tieferen Einblick in gieriges, zögerliches und possessives Verhalten, lesen Sie Java Regex Quantoren.
Anker, Wortgrenzen und Alternativen
Anker stimmen mit einer Position überein, nicht mit einem Zeichen. ^ ist der Anfang der Eingabe (oder der Zeile im Mehrzeilenmodus), $ ist das Ende, und \b ist eine Wortgrenze — der nullbreite Punkt zwischen einem \w und einem \W. Alternation mit | stimmt mit einer der beiden Seiten überein.
"^Hello" // "Hello" only at the start
"\\.txt$" // ".txt" only at the end
"\\bcat\\b" // "cat" as a whole word, not inside "category"
"cat|dog" // "cat" or "dog"
"^(cat|dog)$" // the whole string is exactly "cat" or "dog"Beachten Sie, dass | eine sehr niedrige Priorität hat: ^cat|dog$ bedeutet (^cat)|(dog$), nicht ^(cat|dog)$. Schließen Sie Alternativen in eine Gruppe ein, wenn Sie möchten, dass Anker auf beide zutreffen.
Gruppen, Rückverweise und Inline-Flags
Klammern erstellen eine Erfassungsgruppe — die Engine merkt sich, was jede Gruppe gefunden hat, nummeriert von links nach rechts ab 1. (?:...) ist eine nicht-erfassende Gruppe, wenn Sie nur einen Quantor anwenden möchten. Ein Rückverweis \1 stimmt mit demselben Text überein, den die erste Gruppe erfasst hat. Inline-Flags wie (?i) ändern das Abgleichsverhalten ohne ein separates Pattern.compile-Flag.
"(\\d{4})-(\\d{2})" // group 1 = year, group 2 = month
"(?:ab)+" // repeats "ab" without capturing it
"(\\w+) \\1" // a word followed by itself ("the the")
"(?i)java" // case-insensitive: matches "Java", "JAVA"
"(?m)^line" // multiline: ^ matches at each line startErfassungsgruppen haben ein eigenes Kapitel — Java Regex Gruppen behandelt benannte Gruppen und wie man erfassten Text aus einem Matcher ausliest. Inline-Flags wie (?i) und (?m) sind die musterinternen Äquivalente der Pattern.compile-Flags, die in Java Regex Flags beschrieben werden.
Ein praktisches Beispiel: Die Konstrukte in Aktion
Dieses Programm demonstriert eine Ziffernklasse mit einem Quantor, verankerte Alternation, einen Rückverweis, gieriges versus zögerliches Abgleichen, die Kurzschreibweise \w+ und ein Inline-Flag für Groß-/Kleinschreibungsignorierung — alles mit java.util.regex. Die hier verwendete Syntax treibt die Pattern- und Matcher-API an, die in Java Regex Pattern und Matcher behandelt wird.
Was aus der Ausführung zu entnehmen ist:
\d{4}fand sowohl1995als auch2011, weilfind()nach jedem Treffer in der Eingabe sucht, während eine Klasse mit Quantor (\dwiederholt{4}Mal) die kanonische Methode ist, ein Feld mit fester Breite abzugleichen. Der doppelte Backslash in"\\d{4}"ist das Java-String-Literal, das den einzelnen Backslash erzeugt, den die Regex-Engine erwartet.Pattern.matches("cat|dog", "dog")gabtruezurück, aber dasselbe Muster auf"catnap"gabfalsezurück —matches()verankert implizit die gesamte Eingabe, sodass selbst wenncatincatnapvorkommt, das abschließendenapnicht übereinstimmt und der Gesamtabgleich fehlschlägt.- Der Rückverweis
\1machte aus(\w+) \1"ein Wort gefolgt vom identischen Wort", weshalb estheundismeldete — die beiden Wiederholungen — und jedes Wort ignorierte, das nicht unmittelbar wiederholt wurde. Rückverweise gleichen den erfassten Text ab, nicht das Muster erneut. - Auf derselben
<a><b>-Eingabe verschlang der gierige<.+>den gesamten String, während der zögerliche<.+?>beim ersten>aufhörte und nur<a>lieferte. Dieser einzelne Kontrast ist die häufigste Regex-Fehlerbehebung, die Sie je vornehmen werden: Fügen Sie?zu einem Quantor hinzu, wenn er zu viel erfasst. \w+zählte 3 Token inab, cd-ef!—ab,cdundef— weil,,-und!alles\W-Zeichen (Nicht-Wort-Zeichen) sind, die eine Folge von Wortzeichen unterbrechen. Das Inline-Flag(?i)stimmte dannjavamitJAVAab und zeigt, dass Flags im Muster selbst stehen können, anstatt nur inPattern.compile.