JavaRush /Java-Blog /Random-DE /Reguläre Ausdrücke in Java, Teil 1

Reguläre Ausdrücke in Java, Teil 1

Veröffentlicht in der Gruppe Random-DE
Wir machen Sie auf die Übersetzung einer kurzen Anleitung zu regulären Ausdrücken in der Java-Sprache aufmerksam, die Jeff Friesen für die JavaWorld- Website geschrieben hat . Zur besseren Lesbarkeit haben wir den Artikel in mehrere Teile gegliedert. Reguläre Ausdrücke in Java, Teil 1 - 1

Verwendung der Regular Expression API in Java-Programmen zum Erkennen und Beschreiben von Mustern

Die Zeichen- und verschiedenen String-Datentypen von Java bieten eine Low-Level-Unterstützung für den Mustervergleich, ihre Verwendung für diesen Zweck erhöht jedoch in der Regel die Komplexität des Codes erheblich. Einfacherer und leistungsfähigerer Code wird durch die Verwendung der Regex-API („Regular Expression API“) erhalten. Dieses Tutorial hilft Ihnen beim Einstieg in reguläre Ausdrücke und die Regex-API. Wir besprechen zunächst die drei interessantesten Klassen im Paket im Allgemeinen java.util.regex, werfen dann einen Blick in die Klasse Patternund erkunden ihre ausgefeilten Mustervergleichskonstrukte. Aufmerksamkeit: Sie können den Quellcode (erstellt von Jeff Friesen für die JavaWorld-Site) der Demoanwendung aus diesem Artikel hier herunterladen .

Was sind reguläre Ausdrücke?

Ein regulärer Ausdruck (regular expression/regex/regexp) ist eine Zeichenfolge, die ein Muster darstellt, das einen bestimmten Satz von Zeichenfolgen beschreibt. Das Muster bestimmt, welche Zeilen zur Menge gehören. Das Muster besteht aus Literalen und Metazeichen – Zeichen mit einer besonderen Bedeutung und nicht mit einer wörtlichen Bedeutung. Beim Mustervergleich handelt es sich um eine Textsuche, um Übereinstimmungen zu finden, d. h. Zeichenfolgen, die mit einem regulären Ausdrucksmuster übereinstimmen. Java unterstützt den Mustervergleich über seine Regex-API. Diese API besteht aus drei Klassen: Pattern, Matcherund PatternSyntaxException, die sich im Paket befinden java.util.regex:
  • Klassenobjekte Pattern, auch Vorlagen genannt, sind kompilierte reguläre Ausdrücke.
  • Klassenobjekte Matcheroder Matcher sind Musterinterpretationsmechanismen zum Finden von Übereinstimmungen in Zeichenfolgen (Objekte, deren Klassen eine Schnittstelle implementieren java.lang.CharSequenceund als Textquellen dienen).
  • Klassenobjekte PatternSyntaxExceptionwerden verwendet, um ungültige reguläre Ausdrucksmuster zu beschreiben.
Java bietet auch Unterstützung für den Mustervergleich durch verschiedene Methoden der java.lang.String. Beispielsweise gibt die Funktion nur dann boolean matches (String regex)ein Ergebnis zurück true, wenn die aufrufende Zeichenfolge genau mit dem regulären Ausdruck übereinstimmt regex.
Bequeme Methoden
matches()und andere an regulären Ausdrücken orientierte praktische Methoden der Klasse Stringwerden auf ähnliche Weise wie die Regex-API unter der Haube implementiert.

RegexDemo

Ich habe eine Anwendung erstellt, RegexDemoum reguläre Java-Ausdrücke und verschiedene Methoden von Pattern, Matcherund zu demonstrieren PatternSyntaxException. Unten finden Sie den Quellcode für diese Demoanwendung. Listing 1. Demonstration regulärer Ausdrücke
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
public class RegexDemo
{
   public static void main(String[] args)
   {
      if (args.length != 2)
      {
         System.err.println("usage: java RegexDemo regex input");
         return;
      }
      // Преобразуем символьные последовательности начала новой строки (\n) в символы начала строки.
      args[1] = args[1].replaceAll("\\\\n", "\n");
      try
      {
         System.out.println("regex = " + args[0]);
         System.out.println("input = " + args[1]);
         Pattern p = Pattern.compile(args[0]);
         Matcher m = p.matcher(args[1]);
         while (m.find())
            System.out.println("Found [" + m.group() + "] starting at "
                               + m.start() + " and ending at " + (m.end() - 1));
      }
      catch (PatternSyntaxException pse)
      {
         System.err.println("Неправильное регулярное выражение: " + pse.getMessage());
         System.err.println("Описание: " + pse.getDescription());
         System.err.println("Позиция: " + pse.getIndex());
         System.err.println("Неправильный шаблон: " + pse.getPattern());
      }
   }
}
mainDas erste, was eine Klassenmethode tut, RegexDemoist, ihre Befehlszeile zu überprüfen. Es sind zwei Argumente erforderlich: Das erste ist ein regulärer Ausdruck und das zweite ist der Eingabetext, in dem nach dem regulären Ausdruck gesucht wird. Möglicherweise müssen Sie im Eingabetext ein Zeilenumbruchzeichen verwenden (\n). \Dies kann nur durch die Angabe des Zeichens gefolgt vom Zeichen erfolgen n. Die Funktion main()wandelt diese Zeichenfolge in den Unicode-Wert 10 um. Reguläre Ausdrücke in Java, Teil 1 - 2Der Großteil des Codes RegexDemoist in der enthalten try-catch. Der Block trygibt zunächst den angegebenen regulären Ausdruck und den Eingabetext aus und erstellt dann ein Objekt Pattern, das den kompilierten regulären Ausdruck speichert (reguläre Ausdrücke werden kompiliert, um die Leistung des Mustervergleichs zu verbessern). Ein Matcher wird aus dem Objekt extrahiert Patternund verwendet, um iterativ nach Übereinstimmungen zu suchen, bis alle gefunden sind. Der Block catchruft mehrere Klassenmethoden auf PatternSyntaxException, um nützliche Informationen über die Ausnahme abzurufen. Diese Informationen werden sequentiell an den Ausgabestream ausgegeben. Es besteht noch keine Notwendigkeit, die Details der Funktionsweise des Codes zu kennen: Sie werden klar, wenn wir die API im zweiten Teil des Artikels untersuchen. Sie müssen jedoch Listing 1 kompilieren. Nehmen Sie den Code aus Listing 1 und geben Sie dann zum Kompilieren den folgenden Befehl an der Eingabeaufforderung ein RegexDemo: javac RegexDemo.java

Die Pattern-Klasse und ihre Konstrukte

Die Klasse Pattern, die erste von drei Klassen, aus denen die Regex-API besteht, ist eine kompilierte Darstellung eines regulären Ausdrucks. In der Klassen-SDK-Dokumentation Patternwerden verschiedene reguläre Ausdruckskonstrukte beschrieben. Wenn Sie reguläre Ausdrücke jedoch nicht aktiv verwenden, können Teile dieser Dokumentation verwirrend sein. Was sind Quantoren und was ist der Unterschied zwischen gierigen, widerstrebenden und besitzergreifenden Quantoren? Was sind Zeichenklassen, Boundary-Matcher, Rückverweise und eingebettete Flag-Ausdrücke? Diese und weitere Fragen werde ich in den folgenden Abschnitten beantworten.

Literale Zeichenfolgen

Das einfachste Konstrukt eines regulären Ausdrucks ist eine Literalzeichenfolge. Damit der Mustervergleich erfolgreich ist, muss ein Teil des Eingabetextes mit dem Muster dieses Konstrukts übereinstimmen. Betrachten Sie das folgende Beispiel: java RegexDemo apple applet In diesem Beispiel versuchen wir, eine Übereinstimmung für ein Muster appleim Eingabetext zu finden applet. Das folgende Ergebnis zeigt die gefundene Übereinstimmung:
regex = apple
input = applet
Found [apple] starting at 0 and ending at 4
In der Ausgabe sehen wir den regulären Ausdruck und den Eingabetext sowie einen Hinweis auf eine erfolgreiche Erkennung appleim Applet. Darüber hinaus werden die Start- und Endpositionen dieses Spiels angegeben: 0bzw. 4. Die Startposition gibt die erste Stelle im Text an, an der eine Übereinstimmung gefunden wurde, und die Endposition gibt den letzten Punkt der Übereinstimmung an. Nehmen wir nun an, wir hätten die folgende Befehlszeile eingegeben: java RegexDemo apple crabapple Dieses Mal erhalten wir das folgende Ergebnis, mit unterschiedlichen Start- und Endpositionen:
regex = apple
input = crabapple
Found [apple] starting at 4 and ending at 8
Andernfalls werden mit und appletals regulärem Ausdruck apple– dem Eingabetext – keine Übereinstimmungen gefunden. Der gesamte reguläre Ausdruck muss übereinstimmen, aber in diesem Fall enthält der Eingabetext kein tafter apple. Reguläre Ausdrücke in Java, Teil 1 - 3

Metazeichen

Interessantere reguläre Ausdruckskonstrukte kombinieren Literalzeichen mit Metazeichen. In einem regulären Ausdruck bedeutet a.bdas Punkt-Metazeichen beispielsweise jedes Zeichen zwischen und b. Betrachten Sie das folgende Beispiel: In diesem Beispiel wird sowohl ein regulärer Ausdruck als auch ein Eingabetext verwendet. durchsucht den Text nach Übereinstimmungen, die mit einem beliebigen Zeichen beginnen und mit enden. Die Ergebnisse seiner Ausführung sind wie folgt: (.)ajava RegexDemo .ox "The quick brown fox jumps over the lazy ox.".oxThe quick brown fox jumps over the lazy ox.RegexDemoox.
regex = .ox
input = The quick brown fox jumps over the lazy ox.
Found [fox] starting at 16 and ending at 18
Found [ ox] starting at 39 and ending at 41
In der Ausgabe sehen wir zwei Übereinstimmungen: foxund ox(mit einem Leerzeichen davor). Das Metazeichen . entspricht fim ersten Fall einem Zeichen und im zweiten Fall einem Leerzeichen. .oxWas passiert, wenn Sie es durch ein Metazeichen ersetzen .? Das ist das, was wir als Ergebnis der folgenden Befehlszeile erhalten: java RegexDemo . "The quick brown fox jumps over the lazy ox." Da das Punkt-Metazeichen mit jedem Zeichen übereinstimmt, RegexDemowerden Übereinstimmungen ausgegeben, die für alle Zeichen (einschließlich des abschließenden Punktzeichens) des Eingabetextes gefunden wurden:
regex = .
input = The quick brown fox jumps over the lazy ox.
Found [T] starting at 0 and ending at 0
Found [h] starting at 1 and ending at 1
Found [e] starting at 2 and ending at 2
Found [ ] starting at 3 and ending at 3
Found [q] starting at 4 and ending at 4
Found [u] starting at 5 and ending at 5
Found [i] starting at 6 and ending at 6
Found [c] starting at 7 and ending at 7
Found [k] starting at 8 and ending at 8
Found [ ] starting at 9 and ending at 9
Found [b] starting at 10 and ending at 10
Found [r] starting at 11 and ending at 11
Found [o] starting at 12 and ending at 12
Found [w] starting at 13 and ending at 13
Found [n] starting at 14 and ending at 14
Found [ ] starting at 15 and ending at 15
Found [f] starting at 16 and ending at 16
Found [o] starting at 17 and ending at 17
Found [x] starting at 18 and ending at 18
Found [ ] starting at 19 and ending at 19
Found [j] starting at 20 and ending at 20
Found [u] starting at 21 and ending at 21
Found [m] starting at 22 and ending at 22
Found [p] starting at 23 and ending at 23
Found [s] starting at 24 and ending at 24
Found [ ] starting at 25 and ending at 25
Found [o] starting at 26 and ending at 26
Found [v] starting at 27 and ending at 27
Found [e] starting at 28 and ending at 28
Found [r] starting at 29 and ending at 29
Found [ ] starting at 30 and ending at 30
Found [t] starting at 31 and ending at 31
Found [h] starting at 32 and ending at 32
Found [e] starting at 33 and ending at 33
Found [ ] starting at 34 and ending at 34
Found [l] starting at 35 and ending at 35
Found [a] starting at 36 and ending at 36
Found [z] starting at 37 and ending at 37
Found [y] starting at 38 and ending at 38
Found [ ] starting at 39 and ending at 39
Found [o] starting at 40 and ending at 40
Found [x] starting at 41 and ending at 41
Found [.] starting at 42 and ending at 42
Metazeichen zitieren
Um .ein beliebiges anderes Metazeichen als Literalzeichen in einem regulären Ausdruckskonstrukt anzugeben, müssen Sie es auf eine der folgenden Arten maskieren:
  • Stellen Sie ihm einen Backslash voran.
  • Platzieren Sie dieses Metazeichen zwischen \Qund \E(zum Beispiel \Q.\E).
Denken Sie daran, alle Zeichen zu duplizieren, die im Zeichenfolgenliteral vorkommen, z. B. String regex = "\\.";Backslashes (z. B. \\.oder \\Q.\\E). Duplizieren Sie nicht die Backslashes, die Teil eines Befehlszeilenarguments sind.

Charakterklassen

Manchmal müssen Sie die gesuchten Übereinstimmungen auf einen bestimmten Zeichensatz beschränken. Durchsuchen Sie beispielsweise den Text nach den Vokalen a, e, i, ound u, wobei jedes Vorkommen eines Vokalbuchstabens als Übereinstimmung gewertet wird. Bei der Lösung solcher Probleme helfen uns Zeichenklassen, die Zeichensätze zwischen den Metazeichen eckiger Klammern ( [ ]) definieren. Die Klasse Patternunterstützt einfache Zeichenklassen, Bereichsklassen, Umkehr-, Vereinigungs-, Schnitt- und Subtraktionsklassen. Wir werden sie uns jetzt alle ansehen.

Einfache Zeichenklassen

Eine einfache Zeichenklasse besteht aus nebeneinander angeordneten Zeichen und entspricht nur diesen Zeichen. Beispielsweise [abc]entspricht die Klasse den Zeichen a, bund c. Betrachten Sie das folgende Beispiel: java RegexDemo [csw] cave Wie Sie den Ergebnissen entnehmen können, handelt es sich in diesem Beispiel nur um das Zeichen, cfür das es eine Übereinstimmung gibt in cave:
regex = [csw]
input = cave
Found [c] starting at 0 and ending at 0

Invertierte Zeichenklassen

Eine invertierte Zeichenklasse beginnt mit einem Metazeichen ^und entspricht nur den Zeichen, die nicht darin enthalten sind. Beispielsweise [^abc]stimmt die Klasse mit allen Zeichen außer a, bund überein c. Betrachten Sie das folgende Beispiel: java RegexDemo "[^csw]" cave Beachten Sie, dass auf meinem Betriebssystem (Windows) doppelte Anführungszeichen erforderlich sind, da die Shell sie ^als Escape-Zeichen behandelt. Wie Sie sehen, wurden in diesem Beispiel nur die Zeichen a, vund gefunden e, für die es Übereinstimmungen gibt in cave:
regex = [^csw]
input = cave
Found [a] starting at 1 and ending at 1
Found [v] starting at 2 and ending at 2
Found [e] starting at 3 and ending at 3

Bereichszeichenklassen

Eine Bereichszeichenklasse besteht aus zwei durch einen Bindestrich ( -) getrennten Zeichen. Alle Zeichen, beginnend mit dem Zeichen links vom Bindestrich und endend mit dem Zeichen rechts vom Bindestrich, sind Teil des Bereichs. Der Bereich entspricht beispielsweise [a-z]allen lateinischen Kleinbuchstaben. Dies entspricht der Definition einer einfachen Klasse [abcdefghijklmnopqrstuvwxyz]. Betrachten Sie das folgende Beispiel: java RegexDemo [a-c] clown In diesem Beispiel wird nur das Zeichen gefunden, cfür das es eine Übereinstimmung gibt clown:
regex = [a-c]
input = clown
Found [c] starting at 0 and ending at 0
Reguläre Ausdrücke in Java, Teil 2 Reguläre Ausdrücke in Java, Teil 3 Reguläre Ausdrücke in Java, Teil 4 Reguläre Ausdrücke in Java, Teil 5
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION