Was ist ein regulärer RegEx-Ausdruck?
Tatsächlich ist ein regulärer Ausdruck (RegEx in Java) ein Muster zum Suchen nach einer Zeichenfolge im Text. In Java ist die anfängliche Darstellung dieses Musters immer ein String, also ein Objekt der String-Klasse. Allerdings kann nicht jede beliebige Zeichenfolge in einen regulären Ausdruck kompiliert werden, sondern nur solche, die den Regeln zum Schreiben eines regulären Ausdrucks folgen – der in der Sprachspezifikation definierten Syntax. Zum Schreiben eines regulären Ausdrucks werden alphabetische und numerische Zeichen sowie Metazeichen verwendet – Zeichen, die in der Syntax regulärer Ausdrücke eine besondere Bedeutung haben. Zum Beispiel:String regex = "java"; // String-Vorlage „Java“;
String regex = "\\d{3}"; // String-Vorlage aus drei numerischen Zeichen;
Erstellen regulärer Ausdrücke in Java
Um einen RegEx in Java zu erstellen, müssen Sie zwei einfache Schritte ausführen:- Schreiben Sie es als String unter Verwendung der regulären Ausdruckssyntax.
- Kompilieren Sie diese Zeichenfolge in einen regulären Ausdruck.
Pattern
. Dazu müssen Sie eine der beiden in der Klasse verfügbaren statischen Methoden aufrufen compile
. Die erste Methode benötigt ein Argument – ein String-Literal eines regulären Ausdrucks, und die zweite – plus einen weiteren Parameter, der den Modus zum Vergleichen der Vorlage mit Text aktiviert:
public static Pattern compile (String literal)
public static Pattern compile (String literal, int flags)
Die Liste der möglichen Parameterwerte flags
wird in der Klasse definiert Pattern
und steht uns als statische Klassenvariablen zur Verfügung. Zum Beispiel:
Pattern pattern = Pattern.compile("java", Pattern.CASE_INSENSITIVE);//Die Suche nach Übereinstimmungen mit dem Muster erfolgt ohne Berücksichtigung der Groß-/Kleinschreibung.
Im Wesentlichen handelt es sich bei der Klasse Pattern
um einen Konstruktor für reguläre Ausdrücke. Unter der Haube ruft die Methode compile
den privaten Konstruktor der Klasse auf, Pattern
um eine kompilierte Ansicht zu erstellen. Diese Methode zum Erstellen einer Vorlageninstanz wird mit dem Ziel implementiert, sie als unveränderliches Objekt zu erstellen. Beim Erstellen wird eine Syntaxprüfung des regulären Ausdrucks durchgeführt. Bei Fehlern in der Zeile wird eine Ausnahme generiert PatternSyntaxException
.
Syntax für reguläre Ausdrücke
Die Syntax regulärer Ausdrücke basiert auf der Verwendung von Symbolen<([{\^-=$!|]})?*+.>
, die mit alphabetischen Zeichen kombiniert werden können. Abhängig von ihrer Rolle können sie in mehrere Gruppen eingeteilt werden:
Metazeichen | Zweck |
---|---|
^ | Anfang der Zeile |
$ | Ende der Linie |
\B | Wortgrenze |
\B | keine Wortbeschränkung |
\A | Beginn der Eingabe |
\G | Ende des vorherigen Spiels |
\Z | Ende der Eingabe |
\z | Ende der Eingabe |
Metazeichen | Zweck |
---|---|
\D | digitales Symbol |
\D | nicht numerisches Zeichen |
\S | Leerzeichen |
\S | Nicht-Leerzeichen |
\w | alphanumerisches Zeichen oder Unterstrich |
\W | jedes andere Zeichen als ein alphabetischer, numerischer oder Unterstrich |
. | irgendein Charakter |
Metazeichen | Zweck |
---|---|
\T | Tabulatorzeichen |
\N | Newline-Zeichen |
\R | Wagenrücklaufzeichen |
\F | Gehe zu einer neuen Seite |
\u0085 | Zeichen der nächsten Zeile |
\ u 2028 | Zeilentrennzeichen |
\ u 2029 | Absatztrennzeichen |
Metazeichen | Zweck |
---|---|
[a B C] | eines der oben genannten (a, b oder c) |
[^abc] | alle anderen als die aufgeführten (nicht a, b, c) |
[a-zA-Z] | Bereichszusammenführung (bei den lateinischen Zeichen a bis z wird die Groß-/Kleinschreibung nicht beachtet) |
[Anzeige[mp]] | Verkettung von Zeichen (a bis d und m bis p) |
[az&&[def]] | Schnittpunkt von Symbolen (Symbole d,e,f) |
[az&&[^bc]] | Subtrahieren von Zeichen (Zeichen a, dz) |
Metazeichen | Zweck |
---|---|
? | einer oder fehlt |
* | Null oder mehrmals |
+ | einmal oder mehrmals |
{N} | n mal |
{N,} | n-mal oder öfter |
{n,m} | nicht weniger als n-mal und nicht mehr als m-mal |
Gieriger Quantifizierermodus
Eine Besonderheit von Quantifizierern ist die Möglichkeit, sie in verschiedenen Modi zu verwenden: gierig, supergierig und faul. Der Extra-Greedy-Modus wird durch Hinzufügen des Symbols „ “ nach dem Quantor aktiviert+
, der Lazy-Modus durch Hinzufügen des Symbols „ ?
“. Zum Beispiel:
„A.+a“ // gieriger Modus
„A.++a“ // Übergieriger Modus
„A.+?a“ // Lazy-Modus
Versuchen wir am Beispiel dieser Vorlage zu verstehen, wie Quantoren in verschiedenen Modi funktionieren. Standardmäßig arbeitet der Quantifizierer im Greedy-Modus. Dies bedeutet, dass nach der längstmöglichen Übereinstimmung in der Zeichenfolge gesucht wird. Als Ergebnis der Ausführung dieses Codes:
public static void main(String[] args) {
String text = „Egor Alla Alexander“;
Pattern pattern = Pattern.compile(„A.+a“);
Matcher matcher = pattern.matcher(text);
while (matcher.find()) {
System.out.println(text.substring(matcher.start(), matcher.end()));
}
}
Wir erhalten die folgende Ausgabe: Alla Alexa Der Suchalgorithmus für ein bestimmtes Muster „ А.+а
“ wird in der folgenden Reihenfolge ausgeführt:
-
Im angegebenen Muster ist das erste Zeichen der russische Buchstabe
А
.Matcher
gleicht es mit jedem Zeichen des Textes ab, beginnend bei Position Null. An Position Null in unserem Text befindet sich ein SymbolЕ
, dasMatcher
die Zeichen im Text der Reihe nach durchgeht, bis es eine Übereinstimmung mit dem Muster findet. In unserem Beispiel ist dies das Symbol an Position Nr. 5. -
Nachdem eine Übereinstimmung mit dem ersten Zeichen des Musters gefunden wurde,
Matcher
wird die Übereinstimmung mit dem zweiten Zeichen des Musters überprüft. In unserem Fall ist das das Symbol „.
“, das für ein beliebiges Zeichen steht.An sechster Stelle steht das Buchstabensymbol
л
. Natürlich entspricht es dem Muster „beliebiges Zeichen“. -
Matcher
fährt mit der Prüfung des nächsten Zeichens aus dem Muster fort. In unserer Vorlage wird es mit dem.+
Quantifizierer „ “ angegeben. Da die Anzahl der Wiederholungen von „beliebigem Zeichen“ im Muster ein oder mehrere Male beträgt,Matcher
nimmt es der Reihe nach das nächste Zeichen aus der Zeichenfolge und prüft es auf Übereinstimmung mit dem Muster, solange die Bedingung „beliebiges Zeichen“ erfüllt ist. in unserem Beispiel - bis zum Ende der Zeile (von Position Nr. 7 - Nr. 18 des Textes).Tatsächlich
Matcher
erfasst es die gesamte Linie bis zum Ende – hier manifestiert sich seine „Gier“. -
Nachdem
Matcher
das Ende des Textes erreicht und die Prüfung auf denА.+
Teil „ “ des Musters abgeschlossen ist, beginnt Matcher mit der Prüfung auf den Rest des Musters – den Buchstabenа
. Da der Text in Vorwärtsrichtung beendet ist, erfolgt die Prüfung in Rückwärtsrichtung, beginnend mit dem letzten Zeichen: -
Matcher
„merkt“ sich die Anzahl der Wiederholungen im Muster „.+
“, bei der es das Ende des Textes erreicht hat, reduziert also die Anzahl der Wiederholungen um eins und prüft das Muster auf den Text, bis eine Übereinstimmung gefunden wird:
Ultra-gieriger Quantifizierermodus
Im Super-Greedy-Modus funktioniert der Matcher ähnlich wie der Greedy-Modus-Mechanismus. Der Unterschied besteht darin, dass beim Erfassen des Textes bis zum Ende der Zeile keine Rückwärtssuche erfolgt. Das heißt, die ersten drei Stufen im Super-Greedy-Modus ähneln dem Greedy-Modus. Nachdem der gesamte String erfasst wurde, fügt der Matcher den Rest des Musters hinzu und vergleicht ihn mit dem erfassten String. In unserem Beispiel werden beim Ausführen der Hauptmethode mit dem Muster „А.++а
“ keine Übereinstimmungen gefunden.
Lazy-Quantifier-Modus
-
In diesem Modus wird in der Anfangsphase wie im Greedy-Modus nach einer Übereinstimmung mit dem ersten Zeichen des Musters gesucht:
-
Als nächstes sucht es nach einer Übereinstimmung mit dem nächsten Zeichen im Muster – einem beliebigen Zeichen:
-
Im Gegensatz zum Greedy-Modus sucht der Lazy-Modus nach der kürzesten Übereinstimmung im Text. Nachdem also eine Übereinstimmung mit dem zweiten Zeichen des Musters gefunden wurde, das durch einen Punkt angegeben ist und mit dem Zeichen an Position Nr. 6 des Textes übereinstimmt, wird es
Matcher
prüft, ob der Text mit dem Rest des Musters übereinstimmt – dem Zeichen „а
“ . -
Da keine Übereinstimmung mit dem Muster im Text gefunden wurde (an Position Nr. 7 im Text befindet sich das Symbol „
л
“),Matcher
fügt es ein weiteres „beliebiges Zeichen“ im Muster hinzu, da es einmal oder mehrmals angegeben wird. und vergleicht erneut das Muster mit dem Text an den Positionen Nr. 5 bis Nr. 8: -
In unserem Fall wurde eine Übereinstimmung gefunden, aber das Ende des Textes ist noch nicht erreicht. Daher beginnt die Prüfung ab Position Nr. 9 mit der Suche nach dem ersten Zeichen des Musters mit einem ähnlichen Algorithmus und wiederholt sich dann bis zum Ende des Textes.
main
bei Verwendung der Vorlage „ “ das folgende Ergebnis: Alla Alexa Wie aus unserem Beispiel ersichtlich ist, haben wir bei Verwendung verschiedener Quantifizierermodi für dieselbe Vorlage unterschiedliche Ergebnisse erhalten. Daher ist es notwendig, diese Funktion zu berücksichtigen und je nach gewünschtem Ergebnis bei der Suche den gewünschten Modus auszuwählen. А.+?а
Escapezeichen in regulären Ausdrücken
Da ein regulärer Ausdruck in Java, genauer gesagt seine anfängliche Darstellung, mithilfe eines String-Literals angegeben wird, müssen die Regeln der Java-Spezifikation berücksichtigt werden, die sich auf String-Literale beziehen. Insbesondere das Backslash-Zeichen „\
“ in Zeichenfolgenliteralen im Java-Quellcode wird als Escape-Zeichen interpretiert, das den Compiler darauf aufmerksam macht, dass das darauf folgende Zeichen ein Sonderzeichen ist und auf besondere Weise interpretiert werden muss. Zum Beispiel:
String s = "The root directory is \nWindows";//Windows in eine neue Zeile einbinden
String s = "The root directory is \u00A7Windows";//Absatzzeichen vor Windows einfügen
Daher muss es in Zeichenfolgenliteralen, die einen regulären Ausdruck beschreiben und das \
Zeichen „ “ verwenden (z. B. für Metazeichen), verdoppelt werden , damit der Java-Bytecode-Compiler es nicht anders interpretiert. Zum Beispiel:
String regex = "\\s"; // Vorlage für die Suche nach Leerzeichen
String regex = "\"Windows\""; // Muster zur Suche nach der Zeichenfolge „Windows“
Das doppelte Backslash-Zeichen sollte auch als Escapezeichen für Sonderzeichen verwendet werden, wenn diese als „normale“ Zeichen verwendet werden sollen. Zum Beispiel:
String regex = "How\\?"; // Vorlage zum Suchen der Zeichenfolge „Wie?“
Methoden der Pattern-Klasse
Die KlassePattern
verfügt über weitere Methoden zum Arbeiten mit regulären Ausdrücken: String pattern()
– gibt die ursprüngliche Zeichenfolgendarstellung des regulären Ausdrucks zurück, aus dem das Objekt erstellt wurde Pattern
:
Pattern pattern = Pattern.compile("abc");
System.out.println(Pattern.pattern())//"abc"
static boolean matches(String regex, CharSequence input)
– ermöglicht Ihnen, den im Regex-Parameter übergebenen regulären Ausdruck mit dem im Parameter übergebenen Text zu vergleichen input
. Rückgabe: true – wenn der Text mit dem Muster übereinstimmt; falsch – sonst; Beispiel:
System.out.println(Pattern.matches(„A.+a“,„Alla“));//true
System.out.println(Pattern.matches(„A.+a“,„Egor Alla Alexander“));//false
int flags()
– gibt die flags
Parameterwerte der Vorlage zurück, die bei der Erstellung festgelegt wurden, oder 0, wenn dieser Parameter nicht festgelegt wurde. Beispiel:
Pattern pattern = Pattern.compile("abc");
System.out.println(pattern.flags());// 0
Pattern pattern = Pattern.compile("abc",Pattern.CASE_INSENSITIVE);
System.out.println(pattern.flags());// 2
String[] split(CharSequence text, int limit)
– teilt den als Parameter übergebenen Text in ein Array von Elementen auf String
. Der Parameter limit
bestimmt die maximale Anzahl an Treffern, nach denen im Text gesucht wird:
- wann
limit>0
– die Suche nachlimit-1
Übereinstimmungen wird durchgeführt; - at
limit<0
– sucht nach allen Übereinstimmungen im Text - when
limit=0
– sucht nach allen Übereinstimmungen im Text, während leere Zeilen am Ende des Arrays verworfen werden;
public static void main(String[] args) {
String text = „Egor Alla Anna“;
Pattern pattern = Pattern.compile("\\s");
String[] strings = pattern.split(text,2);
for (String s : strings) {
System.out.println(s);
}
System.out.println("---------");
String[] strings1 = pattern.split(text);
for (String s : strings1) {
System.out.println(s);
}
}
Konsolenausgabe: Egor Alla Anna -------- Egor Alla Anna Im Folgenden betrachten wir eine weitere Klassenmethode zum Erstellen eines Objekts Matcher
.
Methoden der Matcher-Klasse
Matcher
ist eine Klasse, aus der ein Objekt zur Suche nach Mustern erstellt wird. Matcher
– Dies ist eine „Suchmaschine“, eine „Maschine“ für reguläre Ausdrücke. Für die Suche müssen ihm zwei Dinge gegeben werden: ein Suchmuster und eine „Adresse“, unter der er suchen kann. Um ein Objekt zu erstellen, Matcher
wird in der Klasse die folgende Methode bereitgestellt Pattern
: рublic Matcher matcher(CharSequence input)
Als Argument akzeptiert die Methode eine Zeichenfolge, in der die Suche durchgeführt wird. Dabei handelt es sich um Objekte von Klassen, die die Schnittstelle implementieren CharSequence
. String
Sie können nicht nur ,, sondern auch , und StringBuffer
als StringBuilder
Argument übergeben . Die Suchvorlage ist das Klassenobjekt, für das die Methode aufgerufen wird . Beispiel für die Erstellung eines Matchers: Segment
CharBuffer
Pattern
matcher
Pattern p = Pattern.compile("a*b");// den regulären Ausdruck in eine Ansicht kompiliert
Matcher m = p.matcher("aaaaab");//Erstellte eine Suchmaschine im Text „aaaaab“ mit dem Muster „a*b“
Jetzt können wir mit Hilfe unserer „Suchmaschine“ nach Übereinstimmungen suchen, die Position der Übereinstimmung im Text herausfinden und den Text mithilfe von Klassenmethoden ersetzen. Die Methode boolean find()
sucht nach der nächsten Übereinstimmung im Text mit dem Muster. Mit dieser Methode und dem Schleifenoperator können Sie den gesamten Text gemäß dem Ereignismodell analysieren (bei Eintreten eines Ereignisses die erforderlichen Operationen ausführen – eine Übereinstimmung im Text finden). int start()
Mit den Methoden dieser Klasse können Sie beispielsweise int end()
die Positionen der Übereinstimmungen im Text ermitteln und mit den Methoden String replaceFirst(String replacement)
die String replaceAll(String replacement)
Übereinstimmungen im Text durch einen anderen Ersatztext ersetzen. Beispiel:
public static void main(String[] args) {
String text = „Egor Alla Anna“;
Pattern pattern = Pattern.compile(„A.+?a“);
Matcher matcher = pattern.matcher(text);
while (matcher.find()) {
int start=matcher.start();
int end=matcher.end();
System.out.println("Übereinstimmung gefunden" + text.substring(start,end) + " с "+ start + " Von " + (end-1) + "Position");
}
System.out.println(matcher.replaceFirst(„Ira“));
System.out.println(matcher.replaceAll(„Olga“));
System.out.println(text);
}
Programmausgabe: Es wurde eine Übereinstimmung gefunden Alla von 5 bis 8 Positionen Es wurde eine Übereinstimmung gefunden Anna von 10 bis 13 Positionen Egor Ira Anna Egor Olga Olga Egor Alla Anna Aus dem Beispiel wird deutlich, dass die Methoden ein neues Objekt replaceFirst
erstellen – einen String, der ist der Quelltext, in dem Übereinstimmungen mit der Vorlage durch den Text ersetzt werden, der als Argument an die Methode übergeben wird. Darüber hinaus ersetzt die Methode nur die erste Übereinstimmung und alle Übereinstimmungen im Test. Der Originaltext bleibt unverändert. Die Verwendung anderer Klassenmethoden sowie Beispiele für reguläre Ausdrücke finden Sie in dieser Artikelserie . Die häufigsten Operationen mit regulären Ausdrücken bei der Arbeit mit Text stammen aus Klassen und sind in die . Dies sind Methoden wie , , , . Aber tatsächlich verwenden sie „unter der Haube“ das und . Wenn Sie also Text ersetzen oder Zeichenfolgen in einem Programm vergleichen müssen, ohne unnötigen Code zu schreiben, verwenden Sie die Methoden von . Wenn Sie erweiterte Funktionen benötigen, denken Sie an Kurse und . replaceAll
String
replaceFirst
replaceAll
Matcher
Pattern
Matcher
String
split
matches
replaceFirst
replaceAll
Pattern
Matcher
String
Pattern
Matcher
Abschluss
Ein regulärer Ausdruck wird in einem Java-Programm mithilfe von Zeichenfolgen beschrieben, die einem durch die Regeln definierten Muster entsprechen. Wenn der Code ausgeführt wird, kompiliert Java diese Zeichenfolge erneut in ein KlassenobjektPattern
und verwendet das Klassenobjekt, Matcher
um Übereinstimmungen im Text zu finden. Wie ich eingangs sagte, werden reguläre Ausdrücke sehr oft auf später verschoben, da sie als schwieriges Thema angesehen werden. Wenn Sie jedoch die Grundlagen von Syntax, Metazeichen und Escapezeichen verstehen und Beispiele für reguläre Ausdrücke studieren, stellen Sie fest, dass diese viel einfacher sind, als es auf den ersten Blick scheint.
GO TO FULL VERSION