From 33613a85afc4b1481367fbe92a17ee59c240250b Mon Sep 17 00:00:00 2001
From: Sven Eisenhauer
+Seit der Version 1.4 enthält das JDK auch Klassen zur Verwendung
+von regulären Ausdrücken. Dabei handelt es sich um Muster,
+die Mengen von Zeichenketten beschreiben und stellvertretend für
+diese stehen.
+
+
+Wenn Sie schon einmal die Datei-Suchfunktionalität Ihres Betriebssystems
+verwendet haben, haben Sie wahrscheinlich - ohne es zu bemerken -
+einen regulären Ausdruck verwendet. Um beispielsweise alle Dateien
+in einem Ordner aufzulisten, suchen Sie typischerweise mit dem Muster
+*.*. Dabei steht der Stern stellvertretend
+für eine beliebige Zeichenkette und schon haben Sie einen (wenn
+auch recht einfachen) regulären Ausdruck verwendet, um nicht
+jeden Dateinamen einzeln hinschreiben zu müssen.
+
+
+
+
+
+Um einen regulären Ausdruck zu erzeugen, hält das JDK die
+Klasse Pattern im Package java.util.regex
+bereit. So ist a*b beispielsweise
+ein Pattern zur Beschreibung
+der Zeichenketten b, ab,
+aab und so weiter. Wobei der
+Stern - wie allgemein üblich - für eine beliebige Menge
+von Zeichen steht. Der obige Ausdruck ließt sich also: »Eine
+beliebige Anzahl von kleinen as,
+gefolgt von einem b«.
+
+
+Die folgende Tabelle zeigt einige häufig verwendete Platzhalter.
+Die Möglichkeiten regulärer Ausdrücke in Java sind
+dabei so vielfältig, dass Sie allein ein ganzes Kapitel füllen
+würden. Eine vollständige Liste findet man z.B. in den JavaDocs
+zur Klasse Pattern.
+
+
+
+Tabelle 17.1: Häufige Elemente für reguläre Ausdrücke
+in Java
+
+Achten Sie bei der Programmierung von regulären Ausdrücken
+darauf, dass das Baskslash-Zeichen (\)
+in Strings reserviert ist und durch einen doppelten Backslash (\\)
+kodiert werden muss.
+Während die Klasse Pattern
+einen regulären Ausdruck repräsentiert, können Sie
+mit Hilfe der Methode matcher
+ein Matcher-Objekt erzeugen,
+das verwendet werden kann, um eine beliebige Zeichenkette auf den
+regulären Ausdruck zu testen.
+
+
+Die Klassen für Pattern und Matcher sind dabei getrennt worden,
+da erstere auf der einen Seite relativ komplexe Objekte sind, auf
+der anderen allerdings auch threadsafe programmiert sind und in nebenläufigen
+Programmen von verschiedenen Threads gemeinsam genutzt werden können.
+Matcher auf der anderen Seite
+sind leichtgewichtige Objekte, die nur von einem Thread verwendet
+werden sollten. In einem Satz: Sie können jeden benötigten
+Ausdruck durch ein global zu verwendendes Pattern
+beschreiben und von diesem bei Bedarf beliebig viele Matcher-Objekte
+erzeugen lassen.
+
+
+
+
+
+Neben der Möglichkeit, Zeichenketten untereinander auf (partielle)
+Gleichheit zu überprüfen, wie es in Abschnitt 11.2.4
+beschrieben wird, kann mit Hilfe von regulären Ausdrücken
+auch überprüft werden, ob eine Zeichenkette von einem Ausdruck
+beschrieben wird. Hierzu erzeugt man zunächst ein Pattern-Objekt,
+das den Ausdruck repräsentiert und anschließend ein Matcher-Objekt,
+das zum Testen verwendet werden kann. Das folgende Listing verdeutlicht
+dies:
+
+
+
+
+
+
+ Titel
+ Inhalt
+ Suchen
+ Index
+ DOC
+ Handbuch der Java-Programmierung, 5. Auflage
+
+ <<
+ <
+ >
+ >>
+ API
+ Kapitel 17 - Utility-Klassen II
+
+
+
+
+
+17.1 Reguläre Ausdrücke
+
+
+
+
+17.1.1 Die Klasse Pattern
+
+
+
+
+
+
+Symbol
+Bedeutung
+
+.
+Ein beliebiges einzelnes Zeichen
+
+*
+Eine beliebige Menge von Zeichen
+
+\d
+Eine Zahl zwischen 0 und 9
+
+\D
+Ein Zeichen das keine Zahl darstellt.
+
+\s
+Ein beliebiges Leerzeichen (Whitespace)
+
+\S
+Ein Zeichen, das kein Leerzeichen ist
+
+
+
+
+
+
+
+
+
+![]()
+
+![]()
+
+
+
+![]()
+
+
+
+
+
+ Warnung
+
+
17.1.2 Die Klasse Matcher
+
+17.1.3 Vergleich einer Zeichenkette mit einem regulären Ausdruck
+
+
+
+
+Listing 17.1: Reguläre Ausdrücke
+
+
+
+
+
+001 /* Listing1701.java */
+002
+003 import java.util.regex.*;
+004
+005 public class Listing1701
+006 {
+007 public static void main(String[] args)
+008 {
+009 // Erzeugen eines Pattern-Objektes für den Ausdruck a*b
+010 Pattern p = Pattern.compile("a*b");
+011
+012 // Erzeugen eines Matcher-Objektes für die Zeichenkette
+013 Matcher m = p.matcher("aaaaab");
+014
+015 // Test, ob die Zeichenkette vom Ausdruck beschrieben wird
+016 boolean b = m.matches();
+017 }
+018 }
+
+
+Listing1701.java
+
+Auffällig an diesem Listing ist, dass weder Pattern +noch Matcher über einen +Konstruktor erzeugt werden. Stattdessen verwenden wir die statische +Methode compile, die ein Pattern- +Objekt zurück gibt und die Methode matcher, +um einen Matcher zu erzeugen. +Der Grund liegt möglicherweise darin, dass das JDK die Pattern +auf diese Weise intern cachen kann und auch bei der »zweiten« +Kompilierung das gleiche Objekt zurückgibt - aber verlassen Sie +sich nicht darauf. + +
+Wie bereits weiter oben beschrieben lassen sich einmal erzeugte Pattern +für viele Matcher wiederverwenden und helfen so, wertvolle Ressourcen +zu sparen. Um nur eine einzige Zeichenkette auf ein Pattern zu testen, +kann man aber auch die folgende Kurzform verwenden: + + +
+
+
+
+001 /* Listing1702.java */
+002
+003 import java.util.regex.*;
+004
+005 public class Listing1702
+006 {
+007 public static void main(String[] args)
+008 {
+009 // Testet die Zeichenkette auf das Pattern
+010 boolean b = Pattern.matches("a*b", "aaaaab");
+011 }
+012 }
+
+ |
++Listing1702.java | +
+Bei dieser Kurzversion wird das Pattern intern kompiliert, anschließend +ein passender Matcher erzeugt und schließlich nur das Resultat +zurückgegeben. Dieser »Einzeiler« ist zwar markant, +allerdings lässt sich das Pattern nicht wiederverwenden. + +
+Und es geht sogar noch kürzer und ohne explizite Verwendung der +Klassen im Package java.util.regex, +wie es das folgende Listing demonstriert. Seit dem JDK 5 stellt die +Klasse String nämlich die +Methode matches zur Verfügung, +hinter der sich nichts anderes als oben beschriebene Kurzform verbirgt. + + +
+
+
+
+001 /* Listing1703.java */
+002
+003 public class Listing1703
+004 {
+005 public static void main(String[] args)
+006 {
+007 // Testet die Zeichenkette auf das Pattern
+008 boolean b = "aaaaab".matches("a*b");
+009 }
+010 }
+
+ |
++Listing1703.java | +
+Neben dem Test auf Äquivalenz erlauben es reguläre Ausdrücke +auch, Teile einer Zeichenkette zu ersetzen oder lange Zeichenketten +in mehrere Teile aufzuspalten (engl. Splitting). Für letzteres +besitzt die Klasse Pattern die +Methoden split +
+
+
++public String[] split(CharSequence input) + +public String[] split(CharSequence input, int limit) ++ + |
++java.util.regex.Pattern | +
+Mit Hilfe des zweiten Parameters kann dabei angegeben werden, in wieviele +Teile die Zeichenkette maximal aufgeteilt werden soll. Er ist eine +Obergrenze für die Größe des zurückgegebenen +Arrays. Wird als Limit eine negative Zahl angeben, wird die Zeichenkette +beliebig oft durch das Pattern geteilt. Beide Methoden verhalten sich +dann identisch. + +
+Das folgende Listing zeigt das Splitting der Zeichenkette, die uns +schon im Kapitel über Strings begegnet ist: + + +
+
+
+
+001 /* Listing1704.java */
+002
+003 import java.util.regex.*;
+004
+005 public class Listing1704
+006 {
+007 public static void main(String[] args)
+008 {
+009 // Der zu verwendende Testsatz
+010 String satz = "Dies ist nur ein Test";
+011
+012 // Jedes Whitespace-Zeichen soll zur
+013 // Trennung verwendet werden
+014 Pattern p = Pattern.compile("\\s");
+015
+016 // Verwendung der Methode split
+017 String[] result = p.split(satz);
+018 for (int x=0; x<result.length; x++) {
+019 System.out.println(result[x]);
+020 }
+021 }
+022 }
+
+ |
++Listing1704.java | +
+Soll das Pattern nicht wiederverwendet werden, kann man auch in diesem +Fall auf eine äquivalente Methode der Klasse String +zurückgreifen, wie bereits in Abschnitt 11.2.7 +beschrieben. +
| Titel + | Inhalt + | Suchen + | Index + | DOC + | Handbuch der Java-Programmierung, 5. Auflage, Addison +Wesley, Version 5.0.1 + |
| << + | < + | > + | >> + | API + | © 1998, 2007 Guido Krüger & Thomas +Stark, http://www.javabuch.de + |