W3docs

Java Regex Zeichenklassen

Vordefinierte und benutzerdefinierte Zeichenklassen in Java Regex — \d, \w, \s, Bereiche, Negation und Schnittmengen.

Eine Zeichenklasse ist der Teil eines regulären Ausdrucks, der ein Zeichen aus einer Menge erlaubter Zeichen abgleicht. Wenn Sie \d, [aeiou] oder [^0-9] schreiben, verwenden Sie eine Zeichenklasse. Sie sind der kleinste Baustein fast jedes nützlichen Musters, und Javas java.util.regex-Engine bietet drei Arten: vorgefertigte Kürzel wie \d, benutzerdefinierte Mengen in [...] und Unicode-fähige benannte Klassen wie \p{Lower}. Wer diese beherrscht, dem fällt der Rest von Regex leicht.

Dieses Kapitel behandelt alle drei Arten — benutzerdefinierte Klassen mit Bereichen und Negation, die vordefinierten Kürzel, Mengenoperationen (Vereinigung, Schnittmenge, Subtraktion) sowie benannte Unicode/POSIX-Klassen — und fasst sie in einem ausführbaren Programm zusammen. Wenn Sie neu in Java Regex sind, lesen Sie zuerst die Regex-Einführung und die Regex-Syntax.

Benutzerdefinierte Klassen: Klammern, Bereiche und Negation

Die eckige-Klammer-Klasse [...] gleicht jedes einzelne Zeichen ab, das darin aufgeführt ist. Listen Sie die Zeichen einzeln auf oder verwenden Sie einen Bindestrich für einen Bereich. Setzen Sie ^ direkt nach der öffnenden Klammer, um die Menge zu negieren — es wird jedes Zeichen abgeglichen, das nicht aufgeführt ist.

"[abc]"      // matches one 'a', 'b', or 'c'
"[a-z]"      // any one lowercase letter (a range)
"[A-Za-z0-9]"// any letter or digit (three ranges in one class)
"[^aeiou]"   // any single character that is NOT a vowel

Innerhalb einer Klasse verlieren die meisten Metazeichen ihre besondere Bedeutung, sodass Sie sie selten escapen müssen. Ausnahmen sind ], ^, - und \ — escapen Sie diese, oder positionieren Sie sie so, dass sie nicht fehlgedeutet werden können (ein - am Anfang oder Ende ist ein wörtlicher Bindestrich, kein Bereich).

java.util.regex.Pattern p = java.util.regex.Pattern.compile("[-+0-9]");
System.out.println(p.matcher("-").find());   // true: leading - is literal
System.out.println(p.matcher("*").find());   // false

Vordefinierte Klassen: die Kürzel

Java liefert Kürzel für die Mengen, die Sie ständig benötigen. Jede Kleinbuchstaben-Form hat ein Komplement in Großbuchstaben, das alles abgleicht, was die Kleinbuchstaben-Form nicht abgleicht.

KürzelGleicht abÄquivalente Klasse
.jedes Zeichen außer Zeilenterminatoren
\deine Ziffer[0-9]
\Deine Nicht-Ziffer[^0-9]
\wein Wortzeichen[a-zA-Z_0-9]
\Wein Nicht-Wortzeichen[^a-zA-Z_0-9]
\sein Leerzeichen[ \t\n\x0B\f\r]
\Sein Nicht-Leerzeichen[^\s]
Warnung
In Java-Quellcode muss der Backslash selbst escaped werden, daher wird das Regex \d in einem String-Literal als "\\d" geschrieben und \w wird zu "\\w". Den zweiten Backslash zu vergessen ist der häufigste Java-Regex-Fehler — "\d" kompiliert nicht einmal.
String digits = "\\d+";          // regex is \d+  (one or more digits)
String word   = "\\w+";          // regex is \w+
"abc123".replaceAll("\\d", "#"); // "abc###"

Negation vs. Schnittmenge vs. Vereinigung

Eine Klammer-Klasse ist standardmäßig eine Vereinigung[abcxyz] gleicht jedes der sechs Zeichen ab. Java fügt zwei Mengenoperatoren innerhalb von Klassen hinzu. Der &&-Operator bildet eine Schnittmenge (nur Zeichen, die in beiden Mengen vorkommen), und das Verschachteln einer Klasse in eine andere erlaubt die Subtraktion.

KonstruktBedeutung
[a-d[m-p]]Vereinigung: ad oder mp
[a-z&&[aeiou]]Schnittmenge: Kleinbuchstaben, die Vokale sind
[a-z&&[^aeiou]]Subtraktion: Kleinbuchstaben, die keine Vokale sind (Konsonanten)
"[a-z&&[^aeiou]]"  // all lowercase consonants
"[\\p{L}&&[^\\p{Lu}]]" // any letter that is not uppercase

Negation mit ^ kehrt eine ganze Klasse um; Schnittmenge mit && schränkt sie ein. Das richtige Werkzeug zu wählen hält Muster lesbar, anstatt Alternationen aufzuhäufen.

Unicode- und POSIX-benannte Klassen

Für alles jenseits von ASCII verwenden Sie die \p{...}-Familie. Diese benannten Klassen kennen Unicode-Kategorien und POSIX-Gruppen, und \P{...} ist die negierte Form. Sie sind unverzichtbar, sobald Ihre Eingabe akzentuierte Buchstaben, nicht-lateinische Schriften enthält oder Sie einfach aussagekräftige Namen bevorzugen.

KlasseGleicht ab
\p{Lower}ein ASCII-Kleinbuchstabe ([a-z])
\p{Punct}ein Interpunktionszeichen
\p{Alnum}ein ASCII-Buchstabe oder eine Ziffer
\p{L}ein beliebiger Unicode-Buchstabe (mit UNICODE_CHARACTER_CLASS)
\p{IsDigit}eine Unicode-Ziffer
// Make \w, \d, \s honor full Unicode, not just ASCII:
java.util.regex.Pattern uni =
    java.util.regex.Pattern.compile("\\w+", java.util.regex.Pattern.UNICODE_CHARACTER_CLASS);
System.out.println(uni.matcher("café").results().count()); // 1: "café" is one word

Ein ausgearbeitetes Beispiel: jede Klassenart an einem String

Dieses Programm erstellt einen kleinen Helfer, count, der angibt, wie viele Zeichen eines Beispiel-Strings eine einstellige Klasse abgleicht. Denselben String durch Ziffern-, Wort-, Leerzeichen-, Bereichs-, Negations-, Schnittmengen-, Punkt- und POSIX-Klassen zu führen macht die Beziehungen zwischen ihnen konkret — und zeigt eine Klasse bei echter Arbeit innerhalb eines größeren Musters.

java— editable, runs on the server

Was der Durchlauf zeigt:

  • \d und [0-9] melden beide 13 für diesen String — sie sind für ASCII-Eingaben exakt gleichwertig. Eine vordefinierte Klasse ist nur ein eingebauter Name für eine Menge, die man auch selbst ausschreiben könnte; verwenden Sie also das Kürzel für bessere Lesbarkeit.
  • \D und [^0-9] melden beide 30, das Komplement der 13 Ziffern in einem 43-Zeichen-String (13 + 30 = 43). Ein Großbuchstaben-Kürzel und eine negierte Klammer-Klasse sind zwei Schreibweisen desselben Komplements.
  • [a-z&&[aeiou]] meldet 3 — nur die Kleinbuchstaben-Vokale, nämlich das e von Order, das o von cost und das i von ship-by. Das führende O von Order ist ein Großbuchstabe, sodass die Schnittmenge es ausschließt. Der Punkt: && schränkt eine Klasse auf die Zeichen ein, die in beiden Mengen vorkommen, anstatt sie zu vereinigen; daher kommen Großbuchstaben-Vokale nie in Frage.
  • Der Punkt gleicht 43 Zeichen ab, jedes einschließlich Leerzeichen und Interpunktion, weil dieser einzeilige String keinen Zeilenterminator enthält, an dem . stoppen würde. Der Punkt ist die breiteste Klasse von allen, weshalb Sie ihn normalerweise durch eine engere ersetzen.
  • Das Muster [A-Z]\d fand A7: Zeichenklassen dienen nicht nur zum Zählen — kombiniert in einer Sequenz validieren sie Struktur, hier ein Buchstabe unmittelbar gefolgt von einer Ziffer. \p{Punct} fand separat 9 Interpunktionszeichen und zeigt damit, dass benannte POSIX-Klassen neben den Kürzeln funktionieren.

Übungsaufgaben

Übung
Welche Zeichenklasse in einem Java-Regex gleicht jeden einzelnen Kleinbuchstaben ab, der auch ein Vokal ist?
Welche Zeichenklasse in einem Java-Regex gleicht jeden einzelnen Kleinbuchstaben ab, der auch ein Vokal ist?

Wie geht es weiter

Eine Zeichenklasse gleicht ein Zeichen ab; der nächste Schritt ist zu steuern, wie viele davon abgeglichen werden und was mit dem Ergebnis geschieht:

  • Regex-Quantifizierer — fügen Sie +, *, ? und {n,m} hinzu, damit eine Klasse eine Folge von Zeichen abgleicht.
  • Capture-Gruppen — schließen Sie eine Klasse in (...) ein, um eine abgeglichene Teilzeichenkette zu extrahieren.
  • Pattern und Matcher — die API aus jedem obigen Beispiel, vertieft behandelt.
  • Regex-FlagsCASE_INSENSITIVE, UNICODE_CHARACTER_CLASS und weitere Optionen, die das Verhalten von Klassen ändern.
Was this page helpful?