Mit Hilfe von Regulären Ausdrücken (engl. regular expressions) kann eine Zeichenkette nach dem Vorhandensein oder auch dem Nichtvorhandensein bestimmter Zeichenketten untersucht werden. Weiterhin ist es möglich eine Zeichenkette in Teile zu zerlegen oder auch bestimmte Teile durch eine andere Zeichenkette zu ersetzen. Es ist dafür eine spezielle Syntax definiert, mit der die zu suchende Zeichenkette definiert wird. Die in Java verwendete Syntax ist an der in Perl verwendeten Syntax angelegt.
Reguläre Ausdrücke stehen ab Java 1.4 zur Verfügung.
Die zentralen Klassen für reguläre Ausdrücke in Java sind
Pattern
und Matcher
aus dem Package
java.util.regex
. Weiterhin spielt das Interface
java.lang.CharSequence
eine zentrale Rolle bei regulären
Ausdrücken. Klassen, aus dem JDK, die das Interface java.lang.CharSequence
implementieren sind:
java.nio.CharBuffer
javax.swing.text.Segment
java.lang.String
java.lang.StringBuffer
java.lang.StringBuilder
wobei der Klasse java.lang.String
wohl die größte
Bedeutung beigemessen werden muss.
Das nachfolgende Beispiel RegEx1.java zeigt beispielhaft eine Verwendung der Klassen
Pattern
und Mather
.
import java.util.regex.*; public class RegEx1 { public static void main(String[] args){ Pattern pattern = Pattern.compile("123"); Matcher matcher = pattern.matcher("123"); System.out.println(matcher.matches()); } }
Mit Hilfe der Methode matches()
des Klasse Matcher
wird überprüft, ob die gesamte Zeichenkette dem regulärem Ausdruck entspricht.
Da der reguläre Ausdruck nur eine einfache Zeichenkette ist, entspricht dieses Beispiel
dem Aufruf der equals
-Methode aus Object
.
Mit Hilfe der Pattern-Syntax können
Zeichenkettenkombinationen definiert werden, die nicht mit Hilfe der equals
-Methode
(oder ähnlichen) abgefragt werden können.
Da das Pattern und die zu untersuchende Zeichenkette gleich sind, wird auf der Systemausgabe
true
als Ergebnis ausgegeben.
In diesem Abschnitt werden die wichtigsten Methoden der Klassen Pattern
und Matcher
vorgestellt. Einige der hier vorgestellten
Methoden finden sich auch in
der Klasse String
wieder, wo sie aber die gleiche Bedeutung
haben, wie die der hier vorgestellten.
Da die Klasse Pattern
keinen öffentlichen Konstruktor besitzt,
müssen Pattern
-Objekte über eine der compile
-Methoden
beschafft werden:
public static Pattern compile(String regEx) public static Pattern compile(String regEx, int flags)
Eine weitere wichtigste Methode der Klasse Pattern
ist
die matcher(
-Methode, über die man sich ein
Matcher
-Objekt, zur Auswertung des regulären Ausdrucks, besorgen kann.
public Matcher matcher(CharSequence input)
Mit der Methode matches
wird geprüft, ob die gesamte
Zeichenkette dem regulären Ausdruck entspricht.
public boolean matches()
Die find()
ermittelt die nächste Teilzeichenkette,
die dem regulären Ausdruck entspricht. Wird eine Teilzeichenkette
gefunden, ist der Rückgabewert der Methode true
.
Wird keine Teilzeichenkette gefunden ist der Rückgabewert
false
. Die nächste Suche beginnt nach dem Ende
des aktuellen Suchergebnisses.
public boolean find()
Die start()
-Methode liefert den Startindex in
der Zeichenkette, an dem zuletzt eine Untermenge gefunden wurde,
die dem reguären Ausdruck entspricht.
public int start()
Die end()
-Methode liefert den offset-Index in
der Zeichenkette, an dem zuletzt eine Untermenge gefunden wurde,
die dem reguären Ausdruck entspricht.
public int end()
import java.util.regex.*; public class RegEx3 { public static void main(String[] args){ Pattern pattern = Pattern.compile("abc"); Matcher matcher = pattern.matcher("xyzabc123abctttabcft"); System.out.println("matches: "+matcher.matches()); while(matcher.find()){ System.out.println("Pattern found! start: "+matcher.start()+ " end: "+matcher.end()); } } }
Als Ergebnis dieses Programms erscheint folgende Ausgabe auf der Systemausgabe:
matches: false Pattern found! start: 3 end: 6 Pattern found! start: 9 end: 12 Pattern found! start: 15 end: 18
Mit Hilfe von Zeichenklassen läßt sich eine Auswahl von Zeichen (Character) definieren, die gemäß des Patterns zulässig sind oder nicht. Zeichenklassen werden in rechteckigen Klammern definiert und beziehen sich immer auf das nachfolgende einzelne Zeichen (Ausnahme: Verwendung von Quantifizerern).
Nachfolgend einige Beispile für Zeichenklassen.
Zeichenklasse | Bedeutung | |
[abh] |
Eines der Zeichen: a,b oder h | |
[12uf] |
Eines der Zeichen: 1,2,u oder f | |
[^ret] |
Jedes Zeichen ist zulässig mit Ausnahme der Zeichen: r,e und t | |
[a-z] |
Alle Kleinbuchstaben von a bis z | |
[a-zA-F] |
Alle Kleinbuchstaben von a bis z und die Großbuchstabe von A bis E | |
[^4-7] |
Keine der Zeichen 4,5,6 oder 7 | |
[1-6&&[567]] |
Die Zeichen 5 und 6 (Schnittmenge) | |
[1-6&&[^567]] |
Die Zeichen 1, 2, 3 und 4 (Subtraktion) | |
[1-3[a-c]] |
Die Zeichen 1, 2, 3, a, b und c (Vereinigung) |
Im nachfolgendem Beispiel sollen Zeichenketten untersucht werden, ob Sie dem Namen Meier entsprechen. Es soll angenommen werden, dass die genaue Schreibweise unbekannt ist und folgende Schreibweisen als richtige Schreibweisen gelten:
import java.util.regex.*; public class RegEx2 { private Pattern pattern; public static void main(String[] args){ new RegEx2(); } public RegEx2(){ pattern = Pattern.compile("Me[iyj]er"); System.out.println(isMatching("Meier")); System.out.println(isMatching("Marder")); System.out.println(isMatching("Meyer")); System.out.println(isMatching("Meiler")); System.out.println(isMatching("Mejer")); System.out.println(isMatching("Meider")); System.exit(0); } private boolean isMatching(String s){ Matcher matcher = pattern.matcher(s); return matcher.matches(); } }
Das Ergebnis des Ablaufs ist folgende Ausgabe auf der System Konsole:
true
false
true
false
true
false
Um Schreibarbeit zu sparen und um reguläre Ausdrücke lesbarer zu gestalten sind bestimmte Zeichenklassen vordefiniert. Folgende vorderfinierte Zeichenklassen können bei regulären Ausdrücken in Java verwendet werden:
. | Jedes beliebiege Zeichen, wobei Zeilenendzeichen evtl. nicht zählen. | |||
\d | Eine beliebige Zahl: | [0-9] |
||
\D | Keine Zahl: | [^0-9] |
||
\s | Ein "whitespace" Zeichen: | [ \t\n\x0B\f\r] |
||
\S | Kein "whitespace" Zeichen: | [^\s] |
||
\w | Ein Buchstabe, Zahl oder Unterstrich: | [0-9_a-z] |
Quantifizerer erlauben die Angabe, wie oft ein Teil eines regulären Ausdrucks hintereinander vorkommen darf bzw. muss, damit er gefunden wird. Nachfolgend eine Tabelle mit den möglichen Quantifizierern.
Quantifiierer | Bedeutung | ||
Greedy | Relucant | Possesive | |
X? | X?? | X?+ | X, darf einmal oder keinmal vorkommen |
X* | X*? | X*+ | X, keinmal, einmal oder mehrere male |
X+ | X+? | X++ | X, einmal oder mehrere male |
X{n} | X{n}? | X{n}+ | X, genau n mal |
X{n,} | X{n,}? | X{n,}+ | X, mindestens n mal |
X{n,m} | X{n,m}? | X{n,m}+ | X, mindestens n mal aber nicht mehr mals als m |
Mit Hilfe der Boundary Matchers können Randbedingungen definiert werden, die zu treffen müssen, damit der reguläre Ausdruck gefunden wird. Nachfolgende Boundary Matchers sind für reguläre Ausdrücke in Java definiert.
^ | Am Zeeilenanfang | |
$ | Am Zeilenende | |
\b | Am Anfang oder am Ende eines Wortes | |
\B | Nicht am Anfang und nicht am Ende eines Wortes | |
\A | Am Beginn der Eingabe | |
\G | Am Ende des vorherigen Treffers | |
\Z | Am Ende der zu untersuchenden Zeichenkette aber vor Abschlusszeichen (falls vorhanden) | |
\z | Am Ende der zu untersuchenden Zeichenkette |