JavaRush /Java-Blog /Random-DE /Reguläre Ausdrücke in Java (RegEx)

Reguläre Ausdrücke in Java (RegEx)

Veröffentlicht in der Gruppe Random-DE
Reguläre Ausdrücke sind ein Thema, das selbst erfahrene Programmierer oft auf später verschieben. Allerdings werden sich die meisten Java-Entwickler früher oder später mit der Textverarbeitung auseinandersetzen müssen. Am häufigsten - mit Suchvorgängen im Text und Bearbeitung. Ohne reguläre Ausdrücke ist produktiver und kompakter Programmcode rund um die Textverarbeitung schlicht undenkbar. Also hören Sie auf, es aufzuschieben, sondern kümmern wir uns jetzt um die „Stammgäste“. Das ist keine so schwierige Aufgabe.

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:
  1. Schreiben Sie es als String unter Verwendung der regulären Ausdruckssyntax.
  2. Kompilieren Sie diese Zeichenfolge in einen regulären Ausdruck.
Die Arbeit mit regulären Ausdrücken in jedem Java-Programm beginnt mit der Erstellung eines Klassenobjekts 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 flagswird in der Klasse definiert Patternund 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 Patternum einen Konstruktor für reguläre Ausdrücke. Unter der Haube ruft die Methode compileden privaten Konstruktor der Klasse auf, Patternum 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:
1. Metazeichen zum Anpassen von Zeilengrenzen oder Text
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
2. Metazeichen zur Suche nach Zeichenklassen
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
3. Metazeichen für die Suche nach Textbearbeitungssymbolen
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
4. Metazeichen zum Gruppieren von Zeichen
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)
5. Metasymbole zur Angabe der Zeichenanzahl – Quantoren. Der Quantor steht immer hinter einem Zeichen oder einer Zeichengruppe.
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:
  1. Im angegebenen Muster ist das erste Zeichen der russische Buchstabe А. Matchergleicht es mit jedem Zeichen des Textes ab, beginnend bei Position Null. An Position Null in unserem Text befindet sich ein Symbol Е, das Matcherdie 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.

    Reguläre Ausdrücke in Java - 2
  2. Nachdem eine Übereinstimmung mit dem ersten Zeichen des Musters gefunden wurde, Matcherwird die Übereinstimmung mit dem zweiten Zeichen des Musters überprüft. In unserem Fall ist das das Symbol „ .“, das für ein beliebiges Zeichen steht.

    Reguläre Ausdrücke in Java - 3

    An sechster Stelle steht das Buchstabensymbol л. Natürlich entspricht es dem Muster „beliebiges Zeichen“.

  3. Matcherfä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, Matchernimmt 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).

    Reguläre Ausdrücke in Java - 4

    Tatsächlich Matchererfasst es die gesamte Linie bis zum Ende – hier manifestiert sich seine „Gier“.

  4. Nachdem Matcherdas 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:

    Reguläre Ausdrücke in Java - 5
  5. 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: Reguläre Ausdrücke in Java - 6

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. Reguläre Ausdrücke in Java - 7

Lazy-Quantifier-Modus

  1. In diesem Modus wird in der Anfangsphase wie im Greedy-Modus nach einer Übereinstimmung mit dem ersten Zeichen des Musters gesucht:

    Reguläre Ausdrücke in Java - 8
  2. Als nächstes sucht es nach einer Übereinstimmung mit dem nächsten Zeichen im Muster – einem beliebigen Zeichen:

    Reguläre Ausdrücke in Java - 9
  3. 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 Matcherprüft, ob der Text mit dem Rest des Musters übereinstimmt – dem Zeichen „ а“ .

    Reguläre Ausdrücke in Java - 10
  4. Da keine Übereinstimmung mit dem Muster im Text gefunden wurde (an Position Nr. 7 im Text befindet sich das Symbol „ л“), Matcherfü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:

    Reguläre Ausdrücke in Java - 11
  5. 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.

    Reguläre Ausdrücke in Java - 12
Als Ergebnis der Methode erhalten wir mainbei 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 Klasse Patternverfü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 flagsParameterwerte 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 limitbestimmt die maximale Anzahl an Treffern, nach denen im Text gesucht wird:
  • wann limit>0– die Suche nach limit-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;
Beispiel:
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

Matcherist 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, Matcherwird 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. StringSie können nicht nur ,, sondern auch , und StringBufferals StringBuilderArgument übergeben . Die Suchvorlage ist das Klassenobjekt, für das die Methode aufgerufen wird . Beispiel für die Erstellung eines Matchers: SegmentCharBufferPatternmatcher
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 replaceFirsterstellen – 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 . replaceAllStringreplaceFirstreplaceAllMatcherPatternMatcherStringsplitmatchesreplaceFirstreplaceAllPatternMatcherStringPatternMatcher

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 Klassenobjekt Patternund verwendet das Klassenobjekt, Matcherum Ü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.
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION