Java Language
Reguläre Ausdrücke
Suche…
Einführung
Ein regulärer Ausdruck ist eine spezielle Zeichenfolge, die beim Zuordnen oder Finden anderer Zeichenketten oder Zeichenfolgen hilft, wobei eine spezielle, in einem Muster enthaltene Syntax verwendet wird. Java unterstützt die Verwendung regulärer Ausdrücke über das Paket java.util.regex
. In diesem Thema werden Entwickler vorgestellt und anhand von Beispielen erläutert, wie reguläre Ausdrücke in Java verwendet werden müssen.
Syntax
- Pattern patternName = Pattern.compile (Regex);
- Matcher MatcherName = MusterName.Matcher (TextToSearch);
- matcherName.matches () // Gibt "true" zurück, wenn textToSearch genau mit dem regulären Ausdruck übereinstimmt
- matcherName.find () // Durchsucht textToSearch nach der ersten Instanz eines Teilstrings, der der Regex entspricht. Nachfolgende Aufrufe durchsuchen den Rest der Zeichenfolge.
- matcherName.group (groupNum) // Gibt den Teilstring innerhalb einer Erfassungsgruppe zurück
- matcherName.group (groupName) // Gibt den Teilstring innerhalb einer benannten Erfassungsgruppe zurück (Java 7+)
Bemerkungen
Importe
Sie müssen die folgenden Importe hinzufügen, bevor Sie Regex verwenden können:
import java.util.regex.Matcher
import java.util.regex.Pattern
Fallstricke
In Java wird ein Backslash mit einem doppelten Backslash geschützt, daher sollte ein Backslash in der Regex-Zeichenfolge als doppelter Backslash eingegeben werden. Wenn Sie einem doppelten Backslash entgehen müssen (um einen einzelnen Backslash mit dem Regex abgleichen zu können, müssen Sie ihn als vierfachen Backslash eingeben.
Wichtige Symbole erklärt
Charakter | Beschreibung |
---|---|
* | Stimmt mit dem vorhergehenden Zeichen oder Unterausdruck mindestens 0 mal überein |
+ | Ordnen Sie den vorhergehenden Buchstaben oder Unterausdruck mindestens ein Mal zu |
? | Stimmt mit dem vorhergehenden Zeichen oder Unterausdruck 0 oder 1 überein |
Lesen Sie weiter
Das Thema "Regex" enthält weitere Informationen zu regulären Ausdrücken.
Capture-Gruppen verwenden
Wenn Sie einen Teil der Zeichenfolge aus der Eingabezeichenfolge extrahieren müssen, können Sie Erfassungsgruppen für Regex verwenden.
In diesem Beispiel beginnen wir mit einer einfachen Regex: Telefonnummer:
\d{3}-\d{3}-\d{4}
Wenn dem Regex Klammern hinzugefügt werden, wird jeder Satz von Klammern als Erfassungsgruppe betrachtet . In diesem Fall verwenden wir so genannte nummerierte Erfassungsgruppen:
(\d{3})-(\d{3})-(\d{4})
^-----^ ^-----^ ^-----^
Group 1 Group 2 Group 3
Bevor wir es in Java verwenden können, dürfen wir nicht vergessen, die Regeln von Strings zu befolgen und die Backslashes zu umgehen, was folgendes Muster ergibt:
"(\\d{3})-(\\d{3})-(\\d{4})"
Wir müssen zuerst das Regex-Muster kompilieren, um ein Pattern
zu erstellen, und dann brauchen wir einen Matcher
, um unsere Eingabezeichenfolge mit dem Muster Matcher
:
Pattern phonePattern = Pattern.compile("(\\d{3})-(\\d{3})-(\\d{4})");
Matcher phoneMatcher = phonePattern.matcher("abcd800-555-1234wxyz");
Als Nächstes muss der Matcher die erste Untersequenz finden, die der Regex entspricht:
phoneMatcher.find();
Mit der Gruppenmethode können wir nun die Daten aus der Zeichenfolge extrahieren:
String number = phoneMatcher.group(0); //"800-555-1234" (Group 0 is everything the regex matched)
String aCode = phoneMatcher.group(1); //"800"
String threeDigit = phoneMatcher.group(2); //"555"
String fourDigit = phoneMatcher.group(3); //"1234"
Hinweis: Matcher.group()
kann anstelle von Matcher.group(0)
.
In Java 7 wurden benannte Capture-Gruppen eingeführt. Benannte Erfassungsgruppen funktionieren genauso wie nummerierte Erfassungsgruppen (jedoch mit einem Namen anstelle einer Zahl), obwohl es geringfügige Syntaxänderungen gibt. Die Verwendung benannter Capture-Gruppen verbessert die Lesbarkeit.
Wir können den obigen Code ändern, um benannte Gruppen zu verwenden:
(?<AreaCode>\d{3})-(\d{3})-(\d{4})
^----------------^ ^-----^ ^-----^
AreaCode Group 2 Group 3
Um den Inhalt von "AreaCode" zu erhalten, können wir stattdessen Folgendes verwenden:
String aCode = phoneMatcher.group("AreaCode"); //"800"
Regex mit benutzerdefiniertem Verhalten verwenden, indem das Muster mit Flags kompiliert wird
Ein Pattern
kann mit Flags kompiliert werden. Wenn der Regex als literaler String
, verwenden Sie Inline-Modifizierer:
Pattern pattern = Pattern.compile("foo.", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
pattern.matcher("FOO\n").matches(); // Is true.
/* Had the regex not been compiled case insensitively and singlelined,
* it would fail because FOO does not match /foo/ and \n (newline)
* does not match /./.
*/
Pattern anotherPattern = Pattern.compile("(?si)foo");
anotherPattern.matcher("FOO\n").matches(); // Is true.
"foOt".replaceAll("(?si)foo", "ca"); // Returns "cat".
Fluchtfiguren
Allgemein
Um reguläre Ausdrücke ( ?+|
Usw.) in ihrer wörtlichen Bedeutung zu verwenden, müssen sie mit Escapezeichen versehen werden. Im normalen regulären Ausdruck geschieht dies durch einen Backslash \
. Da dies jedoch in Java-Zeichenfolgen eine besondere Bedeutung hat, müssen Sie einen doppelten Backslash \\
.
Diese beiden Beispiele funktionieren nicht:
"???".replaceAll ("?", "!"); //java.util.regex.PatternSyntaxException
"???".replaceAll ("\?", "!"); //Invalid escape sequence
Dieses Beispiel funktioniert
"???".replaceAll ("\\?", "!"); //"!!!"
Aufteilen einer durch Pipe getrennten Zeichenfolge
Dies liefert nicht das erwartete Ergebnis:
"a|b".split ("|"); // [a, |, b]
Dies gibt das erwartete Ergebnis zurück:
"a|b".split ("\\|"); // [a, b]
Backslash abfangen \
Dies gibt einen Fehler:
"\\".matches("\\"); // PatternSyntaxException
"\\".matches("\\\"); // Syntax Error
Das funktioniert:
"\\".matches("\\\\"); // true
Übereinstimmung mit einem Regex-Literal.
Wenn Sie Zeichen finden müssen, die Teil der Syntax für reguläre Ausdrücke sind, können Sie das gesamte Muster oder einen Teil des Musters als Regex-Literal markieren.
\Q
markiert den Anfang des Regex-Literal. \E
markiert das Ende des Regex-Literal.
// the following throws a PatternSyntaxException because of the un-closed bracket
"[123".matches("[123");
// wrapping the bracket in \Q and \E allows the pattern to match as you would expect.
"[123".matches("\\Q[\\E123"); // returns true
Eine einfachere Möglichkeit, dies zu tun, ohne sich an die \Q
Pattern.quote()
und \E
Escape-Sequenzen zu erinnern, ist die Verwendung von Pattern.quote()
"[123".matches(Pattern.quote("[") + "123"); // returns true
Stimmt nicht mit einer bestimmten Zeichenfolge überein
Um etwas zu finden, das keine bestimmte Zeichenfolge enthält, kann ein negatives Lookahead verwendet werden:
Regex-Syntax: (?!string-to-not-match)
Beispiel:
//not matching "popcorn"
String regexString = "^(?!popcorn).*$";
System.out.println("[popcorn] " + ("popcorn".matches(regexString) ? "matched!" : "nope!"));
System.out.println("[unicorn] " + ("unicorn".matches(regexString) ? "matched!" : "nope!"));
Ausgabe:
[popcorn] nope!
[unicorn] matched!
Einen Backslash abgleichen
Wenn Sie einen umgekehrten Schrägstrich in Ihrem regulären Ausdruck abgleichen möchten, müssen Sie ihn deaktivieren.
Backslash ist ein Escape-Zeichen in regulären Ausdrücken. Sie können '\\' verwenden, um auf einen einzelnen Backslash in einem regulären Ausdruck zu verweisen.
Backslash ist jedoch auch ein Escape-Zeichen in Java-Literal-Strings. Um aus einem String-Literal einen regulären Ausdruck zu erstellen, müssen Sie jeden seiner Backslashes mit Escapezeichen versehen. In einem String-Literal kann mit '\\\\' ein regulärer Ausdruck mit '\\' erstellt werden, der wiederum mit '\' übereinstimmen kann.
Stellen Sie sich beispielsweise vor, Zeichenfolgen wie "C: \ dir \ myfile.txt" zu finden. Ein regulärer Ausdruck ([A-Za-z]):\\(.*)
Stimmt überein und stellt den Laufwerksbuchstaben als Erfassungsgruppe bereit. Beachten Sie den doppelten Backslash.
Um dieses Muster in einem Java-String-Literal auszudrücken, muss jeder der umgekehrten Schrägstriche im regulären Ausdruck mit Escapezeichen versehen werden.
String path = "C:\\dir\\myfile.txt";
System.out.println( "Local path: " + path ); // "C:\dir\myfile.txt"
String regex = "([A-Za-z]):\\\\.*"; // Four to match one
System.out.println("Regex: " + regex ); // "([A-Za-z]):\\(.*)"
Pattern pattern = Pattern.compile( regex );
Matcher matcher = pattern.matcher( path );
if ( matcher.matches()) {
System.out.println( "This path is on drive " + matcher.group( 1 ) + ":.");
// This path is on drive C:.
}
Wenn Sie zwei umgekehrte Schrägstriche abgleichen möchten, verwenden Sie acht in einer Literal-Zeichenfolge, um vier im regulären Ausdruck darzustellen, und zwei.
String path = "\\\\myhost\\share\\myfile.txt";
System.out.println( "UNC path: " + path ); // \\myhost\share\myfile.txt"
String regex = "\\\\\\\\(.+?)\\\\(.*)"; // Eight to match two
System.out.println("Regex: " + regex ); // \\\\(.+?)\\(.*)
Pattern pattern = Pattern.compile( regex );
Matcher matcher = pattern.matcher( path );
if ( matcher.matches()) {
System.out.println( "This path is on host '" + matcher.group( 1 ) + "'.");
// This path is on host 'myhost'.
}