Aktionen

Regular Expressions

Aus Java Tutorial - Java lernen

Java stellt das Paket java.util.regex für den Mustervergleich mit regulären Ausdrücken zur Verfügung. Die regulären Ausdrücke von Java sind der Programmiersprache Perl sehr ähnlich und sehr leicht zu erlernen.

Ein regulärer Ausdruck ist eine spezielle Zeichenfolge, die Ihnen hilft, andere Zeichenfolgen oder Zeichensätze mit Hilfe einer speziellen Syntax, die in einem Muster enthalten ist, abzugleichen oder zu finden. Sie können zum Suchen, Bearbeiten oder Manipulieren von Text und Daten verwendet werden.

Das Paket java.util.regex besteht hauptsächlich aus den folgenden drei Klassen:

  • Pattern-Klasse - Ein Pattern-Objekt ist eine kompilierte Darstellung eines regulären Ausdrucks. Die Klasse Pattern stellt keine öffentlichen Konstruktoren zur Verfügung. Um ein Pattern zu erstellen, müssen Sie zunächst eine ihrer öffentlichen statischen compile()-Methoden aufrufen, die dann ein Pattern-Objekt zurückgibt. Diese Methoden akzeptieren einen regulären Ausdruck als erstes Argument.
  • Matcher-Klasse - Ein Matcher-Objekt ist der Motor, der das Muster interpretiert und Abgleichsoperationen gegen eine Eingabezeichenfolge durchführt. Wie die Pattern-Klasse definiert auch die Matcher-Klasse keine öffentlichen Konstruktoren. Sie erhalten ein Matcher-Objekt, indem Sie die matcher()-Methode für ein Pattern-Objekt aufrufen.
  • PatternSyntaxException - Ein PatternSyntaxException-Objekt ist eine nicht angekreuzte Ausnahme, die einen Syntaxfehler in einem Muster mit regulärem Ausdruck anzeigt.

Erfassen von Gruppen

Das Erfassen von Gruppen ist eine Möglichkeit, mehrere Zeichen als eine Einheit zu behandeln. Sie werden erstellt, indem die zu gruppierenden Zeichen innerhalb eines Satzes von Klammern gesetzt werden. Beispielsweise erzeugt der reguläre Ausdruck (dog) eine einzige Gruppe, die die Buchstaben "d", "o" und "g" enthält.

Erfassungsgruppen werden nummeriert, indem ihre öffnenden Klammern von links nach rechts gezählt werden. In dem Ausdruck ((A)(B(C))) gibt es zum Beispiel vier solcher Gruppen:

  • ((A)(B(C)))
  • (A)
  • (B(C))
  • (C)

Um herauszufinden, wie viele Gruppen in dem Ausdruck vorhanden sind, rufen Sie die Methode groupCount auf einem Matcher-Objekt auf. Die Methode groupCount gibt einen int zurück, der die Anzahl der im Muster des Matcher-Objekts vorhandenen Erfassungsgruppen anzeigt.

Es gibt auch eine spezielle Gruppe, Gruppe 0, die immer den gesamten Ausdruck darstellt. Diese Gruppe ist in der von groupCount gemeldeten Gesamtsumme nicht enthalten.

Beispiel

Das folgende Beispiel veranschaulicht, wie man eine Ziffernfolge aus der gegebenen alphanumerischen Zeichenfolge findet:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexMatches {

   public static void main( String args[] ) {
      // Zeichenfolge, die gescannt werden muss, um das Muster zu finden.
      String line = "This order was placed for QT3000! OK?";
      String pattern = "(.*)(\\d+)(.*)";

      // Erstellen eines Pattern-Objekts
      Pattern r = Pattern.compile(pattern);

      // Erstellen Sie nun ein Matcher-Objekt.
      Matcher m = r.matcher(line);
      if (m.find( )) {
         System.out.println("Found value: " + m.group(0) );
         System.out.println("Found value: " + m.group(1) );
         System.out.println("Found value: " + m.group(2) );
      }else {
         System.out.println("NO MATCH");
      }
   }
}

Dies wird zu folgendem Ergebnis führen:

Ausgabe

Found value: This order was placed for QT3000! OK?
Found value: This order was placed for QT300
Found value: 0

Regular Expression Syntax

Hier ist die Tabelle mit allen in Java verfügbaren Metazeichensyntaxen für reguläre Ausdrücke:

Nummer Subexpression Treffer
1 ^ Entspricht dem Anfang der Linie.
2 $ Entspricht dem Ende der Linie.
3 . Entspricht jedem einzelnen Zeichen außer Zeilenumbruch. Mit der Option m kann es auch mit dem Zeilenumbruch übereinstimmen.
4 [...] Entspricht jedem einzelnen Zeichen in den Klammern.
5 [^...] Passt auf jedes einzelne Zeichen, das nicht in den Klammern steht.
6 \A Anfang der gesamten Zeichenfolge.
7 \z Ende der gesamten Zeichenfolge.
8 \Z Ende der gesamten Zeichenfolge mit Ausnahme des zulässigen Endzeilenabschlusses.
9 re* Entspricht 0 oder mehr Vorkommnissen des vorhergehenden Ausdrucks.
10 re+ Entspricht 1 oder mehr der vorherigen Sache.
11 re? Entspricht 0 oder 1 Vorkommen des vorhergehenden Ausdrucks.
12 re{n} Entspricht genau n Anzahl der Vorkommen des vorhergehenden Ausdrucks.
13 re{n,} Trifft n oder mehr Vorkommnisse des vorhergehenden Ausdrucks.
14 re{n, m} Entspricht mindestens n und höchstens m Vorkommen des vorhergehenden Ausdrucks.
15 b Entspricht entweder a oder b.
16 (re) Gruppiert reguläre Ausdrücke und merkt sich den übereinstimmenden Text.
17 (?: re) Gruppiert reguläre Ausdrücke, ohne sich an den übereinstimmenden Text zu erinnern.
18 (?> re) Entspricht dem unabhängigen Muster ohne Rückverfolgung.
19 \w Entspricht den Wortzeichen.
20 \W Entspricht den Nicht-Wort-Zeichen.
21 \s Entspricht dem Whitespace. Gleich zu [\t\n\r\r\f].
22 \S Entspricht dem Nicht-Whitespace.
23 \d Stimmt mit den Ziffern überein. Gleich zu [0-9].
24 \D Entspricht den Nicht-Ziffern.
25 \A Entspricht dem Anfang der Zeichenfolge.
26 \Z Stimmt mit dem Ende der Zeichenfolge überein. Wenn ein Zeilenumbruch vorhanden ist, stimmt er kurz vor dem Zeilenumbruch überein.
27 \z Stimmt mit dem Ende der Zeichenfolge überein.
28 \G Entspricht dem Punkt, an dem das letzte Spiel beendet wurde.
29 \n Rückverweis zur Erfassung der Gruppennummer "n".
30 \b Entspricht den Wortgrenzen, wenn sie außerhalb der Klammern stehen. Entspricht der Rücktaste (0x08), wenn sie sich innerhalb der Klammern befindet.
31 \B Entspricht den Nicht-Wortgrenzen.
32 \n, \t, etc. Entspricht Zeilenumbrüchen, Zeilenumbruch, Tabulatoren usw.
33 \Q Escape (Zitat) alle Zeichen bis zu \E.
34 \E Beendet das mit \Q begonnene Zitieren.

Methoden der Matcher-Klasse

Hier ist eine Liste von nützlichen Instanzmethoden:

Indexmethoden

Indexmethoden liefern nützliche Indexwerte, die genau zeigen, wo die Übereinstimmung in der Eingabezeichenkette gefunden wurde:

Nummer Methode Beschreibung
1 public int start() Gibt den Startindex des vorherigen Treffers zurück.
2 public int start(int group) Gibt den Startindex der Teilsequenz zurück, die von der gegebenen Gruppe während der vorherigen Match-Operation erfasst wurde.
3 public int end() Gibt den Offset nach dem letzten übereinstimmenden Zeichen zurück.
4 public int end(int group) Gibt den Versatz nach dem letzten Zeichen der Teilsequenz zurück, das von der gegebenen Gruppe während der vorherigen Match-Operation erfasst wurde.

Studienmethoden

Studienmethoden überprüfen die Eingabezeichenfolge und geben eine boolesche Angabe zurück, die anzeigt, ob das Muster gefunden wurde oder nicht:

Nummer Methode Beschreibung
1 public boolean lookingAt() Versucht, die Eingabesequenz, beginnend am Anfang der Region, mit dem Muster abzugleichen.
2 public boolean find() Versucht, die nächste Teilsequenz der Eingabesequenz zu finden, die dem Muster entspricht.
3 public boolean find(int start) Setzt diesen Matcher zurück und versucht dann, die nächste Teilsequenz der Eingabesequenz zu finden, die mit dem Muster übereinstimmt, beginnend mit dem angegebenen Index.
4 public boolean matches() Versuche, die gesamte Region mit dem Muster abzugleichen.

Ersetzungs-Methoden

Ersetzungsmethoden sind nützliche Methoden zum Ersetzen von Text in einer Eingabezeichenkette:

Nummer Methode Beschreibung
1 public Matcher appendReplacement(StringBuffer sb, String replacement) Führt einen nicht abschließenden Anhängen-und-Ersetzen-Schritt ein.
2 public StringBuffer appendTail(StringBuffer sb) Implementiert einen Terminal-Schritt zum Anhängen und Ersetzen.
3 public String replaceAll(String replacement) Ersetzt jede Teilsequenz der Eingabesequenz, die mit dem Muster übereinstimmt, durch die angegebene Ersetzungszeichenfolge.
4 public String replaceFirst(String replacement) Ersetzt die erste Teilsequenz der Eingabesequenz, die mit dem Muster übereinstimmt, durch die angegebene Ersetzungszeichenfolge.
5 public static String quoteReplacement(String s) Gibt eine literale Ersatz-Zeichenfolge für die angegebene Zeichenfolge zurück. Diese Methode erzeugt einen String, der als literaler Ersatz s in der appendReplacement-Methode der Klasse Matcher funktioniert.

Die Start- und Endmethoden

Es folgt das Beispiel, das zählt, wie oft das Wort "Katze" in der Eingabezeichenkette vorkommt:

Beispiel

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexMatches {

   private static final String REGEX = "\\bcat\\b";
   private static final String INPUT = "cat cat cat cattie cat";

   public static void main( String args[] ) {
      Pattern p = Pattern.compile(REGEX);
      Matcher m = p.matcher(INPUT);   // ein Matcher-Objekt erhalten
      int count = 0;

      while(m.find()) {
         count++;
         System.out.println("Match number "+count);
         System.out.println("start(): "+m.start());
         System.out.println("end(): "+m.end());
      }
   }
}

Dies wird zu folgendem Ergebnis führen:

Ausgabe

Match number 1
start(): 0
end(): 3
Match number 2
start(): 4
end(): 7
Match number 3
start(): 8
end(): 11
Match number 4
start(): 19
end(): 22

Sie können sehen, dass in diesem Beispiel Wortgrenzen verwendet werden, um sicherzustellen, dass die Buchstaben "c" "a" "t" nicht nur eine Teilzeichenfolge in einem längeren Wort sind. Es gibt auch einige nützliche Informationen darüber, wo in der Eingabezeichenfolge die Übereinstimmung aufgetreten ist.

Die Startmethode gibt den Startindex der Teilfolge zurück, die von der gegebenen Gruppe während der vorherigen Übereinstimmungsoperation erfasst wurde, und das Ende gibt den Index des letzten übereinstimmenden Zeichens plus eins zurück.

Die matches- und lookingAt-Methoden

Sowohl die matches- als auch die LookingAt-Methode versuchen, eine Eingabesequenz mit einem Muster abzugleichen. Der Unterschied besteht jedoch darin, dass bei bei matches die gesamte Eingabesequenz abgeglichen werden muss, während dies bei lookingAt nicht der Fall ist.

Beide Methoden beginnen immer am Anfang der Eingabezeichenfolge. Hier ist ein Beispiel, das die Funktionsweise erklärt:

Beispiel

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexMatches {

   private static final String REGEX = "foo";
   private static final String INPUT = "fooooooooooooooooo";
   private static Pattern pattern;
   private static Matcher matcher;

   public static void main( String args[] ) {
      pattern = Pattern.compile(REGEX);
      matcher = pattern.matcher(INPUT);

      System.out.println("Current REGEX is: "+REGEX);
      System.out.println("Current INPUT is: "+INPUT);

      System.out.println("lookingAt(): "+matcher.lookingAt());
      System.out.println("matches(): "+matcher.matches());
   }
}

Dies wird zu folgendem Ergebnis führen:

Ausgabe

Current REGEX is: foo
Current INPUT is: fooooooooooooooooo
lookingAt(): true
matches(): false

Die replaceFirst- und replaceAll-Methoden

Die Methoden replaceFirst und replaceAll ersetzen den Text, der einem bestimmten regulären Ausdruck entspricht. Wie aus ihren Namen hervorgeht, ersetzt replaceFirst das erste Vorkommen, und replaceAll ersetzt alle Vorkommen.

Hier ist das Beispiel, das die Funktionalität erklärt:

Beispiel

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexMatches {

   private static String REGEX = "dog";
   private static String INPUT = "The dog says meow. " + "All dogs say meow.";
   private static String REPLACE = "cat";

   public static void main(String[] args) {
      Pattern p = Pattern.compile(REGEX);
      
      // ein Matcher-Objekt erhalten
      Matcher m = p.matcher(INPUT); 
      INPUT = m.replaceAll(REPLACE);
      System.out.println(INPUT);
   }
}

Dies wird zu folgendem Ergebnis führen:

Ausgabe

The cat says meow. All cats say meow.

Die appendReplacement- und appendTail-Methoden

Die Matcher-Klasse bietet auch appendReplacement- und appendTail-Methoden zur Textersetzung.

Hier ist ein Beispiel zur Erläuterung der Funktionalität:

Beispiel

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexMatches {

   private static String REGEX = "a*b";
   private static String INPUT = "aabfooaabfooabfoob";
   private static String REPLACE = "-";
   public static void main(String[] args) {

      Pattern p = Pattern.compile(REGEX);
      
      // ein Matcher-Objekt erhalten
      Matcher m = p.matcher(INPUT);
      StringBuffer sb = new StringBuffer();
      while(m.find()) {
         m.appendReplacement(sb, REPLACE);
      }
      m.appendTail(sb);
      System.out.println(sb.toString());
   }
}

Dies wird zu folgendem Ergebnis führen:

Ausgabe

-foo-foo-foo-

PatternSyntaxException-Klasse-Methoden

Eine PatternSyntaxException ist eine nicht angekreuzte Ausnahme, die auf einen Syntaxfehler in einem Muster regulärer Ausdrücke hinweist. Die Klasse PatternSyntaxException stellt die folgenden Methoden zur Verfügung, mit deren Hilfe Sie feststellen können, was schief gelaufen ist:

Nummer Methode Beschreibung
1 public String getDescription() Ruft die Beschreibung des Fehlers ab.
2 public int getIndex() Ruft den Fehlerindex ab.
3 public String getPattern() Ruft das fehlerhafte Muster des regulären Ausdrucks ab.
4 public String getMessage() Gibt eine mehrzeilige Zeichenfolge zurück, die die Beschreibung des Syntaxfehlers und seinen Index, das Muster des fehlerhaften regulären Ausdrucks und eine visuelle Anzeige des Fehlerindex innerhalb des Musters enthält.