Reguläre Ausdrücke sind Muster, die verwendet werden, um Zeichenkombinationen in Strings finden zu können. In JavaScript sind reguläre Ausdrücke Objekte. Dazu werden Methoden des Objekttyps RegExp zur Verfügung gestellt.
Von der theoretischen Informatik wissen wir, dass reguläre Ausdrücke über einem Alphabet definiert sind als die Menge von Zeichenketten über dem Alphabet, die sich durch Auswahl, Verkettung und Abschluss bilden lassen. In JavaScript wird als Alphabet der Zeichensatz des Rechners genommen. Zusätzlich gibt es Sonderzeichen, wie Steuerelement (Tabulator, Zeilenvorschub usw.). Neben der normalen Verkettung und dem Abschluss kann man Längenbeschränkungen und andere Optionen angeben.
Reguläre Ausdrücke in JavaScript sind ähnlich zu den aus Perl oder PHP4 bekannten Suchmustern.
In JavaScript kann man reguläre Ausdrücke auf zwei Arten nutzten:
Zunächst werden wir die erste Methode verwenden, dann werden wir mit der Klasse RegExp arbeiten.
Ein Benutzer soll in einem Formular eine eMail Adresse eingeben. Dazu wird das Zeichen "@" gesucht.
Im Beispiel wird (in der Funktion test) zunächst ein regulärer Ausdruck mit "var reg = /@/;" definiert. Der Aufruf der Methode "exec" prüft, ob das Muster (/@/) im String vorkommt.
eMial Adressen sind etwas komplexer aufgebaut. So sind eMail Adressen der FHD etwa durch den regulären Ausdruck
/ [a-z]+@fbi\.h-da\.de /i
definiert.
| Beispiel 6.1-2 | |
Nun werden wir den Aufbau von regulären Ausdrücken besprechen.
In JavaScript wird ein regulärer Ausdruck einfach in die Zeichen "/" eingeschlossen.
Jedes Zeichen des Zeichensatzes selbst ist ein regulärer Ausdruck.
/a/ /* a ist ein
regulärer Ausdruck */
/b/ /* b ist ein regulärer Ausdruck */
Eine Verkettung von regulären Ausdrücken ist selbst wieder ein regulärer Ausdruck.
/ab/
/JavaScript Kurs!/
Um einfach zum Ausdruck bringen zu können, dass Groß- oder Kleinschreibung nicht von Interesse ist, kann man nach dem "schließenden /" den Modifikator "i" angeben. Ein weiteres Modifikationssymbol ist "g". Durch ihm wird bei der Methode exec()ein Array von Teilstrings zurückgeliefert, die alle auf den regulären Ausdruck passen.
| regulärer Ausdruck | passt z.B. auf |
|
/ab/i |
ab |
Die Zeichen "." und "+" haben eine besondere Bedeutung. "." passt auf jedes Zeichen (außer dem Zeilenumbruch); durch ein "+" wird zum Ausdruck gebracht, dass das vorherige Zeichen beliebig oft wiederholt wird.
| regulärer Ausdruck | passt z.B. auf |
|
/ab.d/ |
abcd |
|
/ab+x/ |
abbx |
|
/ab.+x/ |
ab1111111111x |
Neben diesen Zeichen haben folgende Zeichen ebenfalls eine besondere Bedeutung:
\ | ( ) [ { ^ $ * ? . +
Soll ein solches Zeichen selbst in einem regulären Ausdruck als Zeichen erscheinen, so ist es durch einen Backslash "\" in seiner Rolle als besonderes Zeichen zu "entwerten".
| regulärer Ausdruck | passt z.B. auf |
|
/a\+b/ |
a+b |
|
/a\\b/ |
a\b |
|
/a\\+/ |
a\ |
Mit dem Backslash sind auch besondere Zeichen einzuleiten; für einen Tabulator steht z.B "\t".
Nachfolgend sind diese Zeichen beschrieben.
| Zeichen | Bedeutung |
|
\n |
Zeilenvorshub |
|
\r |
Wagenrücklauf |
|
\t |
Tabulator |
|
\v |
Vertikaltabulator |
|
\f |
Seitenvorschub |
|
\d |
eine Ziffer (== [0-9]) |
|
\D |
ein Zeichen, dass keine Ziffer ist (==[^0-9]) |
|
\w |
alphanumerisches Zeichen (==[a-zA-Z]) |
|
\W |
nicht alphanumerisches Zeichen (==[^a-zA-Z]) |
|
\s |
whitespace (==[\t\v\n\r\f]) |
|
\S |
kein whitespace (==[^\t\v\n\r\f]) |
|
. |
beliebiges Zeichen |
Im folgenden Beispiel wird geprüft, ob in der Eingabe nach beliebigen Zeichen, ein Wort aus Ziffern enthalten ist.
| Beispiel 6.1-3 | |
Multiplikatoren (oder Quantifikatoren) erlauben es, in einem regulären Ausdruck anzugeben, wie oft ein Muster vorkommen soll. "+" und "*" haben wir bereits gesehen; die Modifikatoren sind in der u.a. Tabelle zusammengefasst:
| Multiplikator | Bedeutung |
|
{m,n} |
mindestens m-mal, höchstens n-mal |
|
{m,} |
mindestens m-mal |
|
{m} |
genau m-mal |
|
* |
0 oder mehrere (=={0,}) |
|
+ |
1 oder mehrere (=={1,}) |
|
? |
0 oder 1 mal (=={0,1}) |
Der reguläre Ausdruck
/a{1,3}bc/
passt z.B. auf die Zeichenfolgen:
abc
aabc
aaabc
aaaabc
aaabcbc
aaaxyaaabc
aber nicht auf
bc
aaxbc
aaabxc
Oft ist es nicht nur interessant zu wissen, ob das Muster zu finden ist, sondern auch wo es in einer Eingabe zu finden ist. Die Methode exec() hat als Rückgabe den Teil des Strings, auf den der reguläre Ausdruck passt, bzw. null, wenn er nicht gefunden wird. (null wird als false interpretiert, deshalb war die if-Abfrage möglich)
Dies ist im nächsten Beispiel demonstriert.
| Beispiel 6.1-4 | |
Wir werden die Methode exec() später noch genauer diskutieren, um z.B. nicht nur das erste, sondern auch die restlichen Auftreten der gefundenen Muster bearbeiten zu können.
Im regulären Ausdruck /abc+/ bezieht sich der Multiplikator "+" das Zeichen "c". Im allgemeinen bezieht sich ein Multiplokator auf den davor stehnden regulären Ausdruck. Dies ist ja kein Widerspruch, "a" ist selbst ein regulärer Ausdruck. Will man, dass der Multiplikator "+" sich auf die Zeichenkette "abc" bezieht, so muss man Klammern: /(abc)+/.
/(abc)+/ passt z.B. auf
xabcabc
xabcabcabc
ababcabcabc123
Alternativen werden durch das Zeichen "|" zu Ausdruck gebracht.
Wenn r1 und r2 reguläre Ausdrücke sind, so ist auch r1|r2 ein regulärer Ausdruck.
Beispiel:
/Schuette|Schütte/ passt auf "Schuette" und "Schütte"
/Sch(ue|ü)tte/ passt auf "Schuette" und "Schütte"
Nehmen wir an, wir wollen ein Muster angeben, so dass nur Worte erkannt werden. In diesem Fall sind besonderen Begrenzungszeichen hilfreich, z.B das Zeichen "\b", das auf eine Wortgrenze passt.
Diesen Begrenzer (oder Anker genannt) werden im folgenden Beispiel verwendet, um eine Login Seite aufzurufen.
| Beispiel 6.1-5 | |
Bei Eingabe von "aschuette" wird die Defaultseite geladen, denn der reguläre Ausdruck passt nicht auf die Eingabe, wenn "a schuette" eingegeben wird, wird meine Startseite geladen.
Folgende Tabelle listet die Begrenzer auf:
| Zeichen | Bedeutung |
| ^ | Anfang eines Strings |
| $ | Ende eines Strings |
| \b | Wortgrenze |
| \B | keine Wortgrenze |
Eine Menge von Zeichen kann man definieren, indem man die Zeichen in geschweifte Klammern setzt. So passt
/[0123456789]/
oder
/[0-9]/
auf Ziffern.
Buchstaben sind somit durch den Ausdruck
[a-zA-Z]
beschrieben.
Vokale werden demnach durch folgenden Ausdruck beschrieben:
/[aeiou]/
Das folgende Beispiel verdeutlicht, wie mit regulären Ausdrücken geprüft werden kann, ob eine Eingabe ausschließlich aus Ziffern besteht.
/^[0-9]+$/
Im letzten Beispiel bedeutet "^" Anfang des Strings. Verwendet man das Zeichen innerhalb einer Zeichenklasse, so hat es die Bedeutung von "NICHT". So passt
/[^0-9]/
auf Strings, die keine Ziffer enthalten.
Mit runden Klammern kann man Zeichen zu einem Ausdruck zusammenfassen. Dadurch wird ein interner Zwischenpuffer angelegt, der später im Ausdruck verwendbar ist, um das gefundene Muster zu referenzieren.
Die gefundenen Teilstrings können dabei durch "\1", "\2" usw. verwendet werden.
/(abc) XXX \1/
passt auf Strings, die mit "abc" beginnen und enden.
/(ab*c) XXX \1/
passt z.B. auf folgende Strings:
ac XXX ac
abc XXX abc
abbc XXX abbc
nicht jedoch auf
ac XXX abc
abc XXX ac
abbc XXXX abbc
Durch folgenden regulären Ausdruck lassen sich einfache XML Tags finden:
/<(.+)>.*<\/\1>/
| Beispiel 6.1-6 | |
Wie muss ein regulärer Ausdruck definiert sein, damit folgende Muster erkannt werden:
Bisher wurden reguläre Ausdrücke "literal" definiert. Nun werden wird die Klasse RegExp diskutieren.
Durch
reg = /abc/i
konnte eine Variable deklariert werden, die als Wert den regulären Ausdruck zugewiesen bekommt.
Mit dem Operator new kann die o.a. Variable wie folgt deklariert werden:
reg = new RegExp("abc", "i")
Bevor ein regulärer Ausdruck bearbeitet werden kann, muss er vom JavaScript Interpreter übersetzt werden. Der Zeitpunkt der Übersetzung ist bei beiden o.a. Methoden der Definition des regulären Ausdruckes unterschiedlich:
Die Klasse RegExp hat drei Methoden:
Mit der Methode compile(regexp, mod) wird der reguläre Ausdruck regexp übersetzt. mod ist dabei ein String von Modifikatoren. Dadurch ist es möglich, einen regulären Ausdruck zur Laufzeit zu ändern:
var red = new RegExp("abc","gi");
....
if (...) reg.compile("xyz", "i")
...
Die Methode exec(str)durchsucht str nach dem Teilstrings, die zum regulären Ausdruck passen. Dabei wird null zurückgeliefert, wenn der das Muster nicht gefunden wird, ansonsten wird ein Array mit folgenden Informationen zurückgegeben:
| Element | Beseutung |
| index | Position des ersten gefundenen Zeichens des Musters in str |
| input | der String, auf den der reguläre Ausdruck angewendet wurde |
| [0] | der Teilstring, der als Letztes gefunden wurde |
| [1], [2], ... | Teilstrings, die durch Verwendung von Klammern gefunden wurden (\1, \2, ...) |
Nach der Ausführung der Methode exec haben die Eigenschaften des RegExp-Objektes folgende Werte:
| Eigenschaft | Wert |
| global | gibt an, ob Modifikator "g" verwendet wurde |
| ignoreCase | gibt an, ob Modifikator "i" verwendet wurde |
| lastIndex | falls "g" gesetzt ist, die Position des Start der nächsten Suche |
| source | der reguläre Ausdruck selbst |
| Beispiel 6.1-7 | |
Die Methode test() prüft, ob das Muster im String vorkommt; in diesem Fall wird true zurückgeliefert ansonsten false.
| Beispiel 6.1-8 | |
Bei der Betrachtung der Klasse Sting sind Methoden besprochen worden, mit denen z.B. Such- und Ersetzoperationen darstellbar waren. Folgende Methoden von String sind auch im Zusammenspiel mit regulären Ausdrücken nutzbar:
Wenn str ein String ist und reg ein regulärer Ausdruck:
var str = new String()
var reg = new RegExp();
dann gilt: str.match(reg) == reg.exec(str)
Wenn str ein String ist und reg ein regulärer Ausdruck:
var str = new String()
var reg = new RegExp();
dann gilt: str.search(reg) == reg.test(str)
Mit der Methode replace() der Klasse String kann man nicht nur einen Text in durch einen anderen ersetzen, man kann auch reguläre Ausdrücke angeben, um Stellen im String, die ersetzt werden sollen zu finden.
Das folgende Beispiel ersetzt alle Auftreten von /a+b/ durch xyz.
| Beispiel 6.1-9 | |
Im zweiten Argument von replace kann man mit $1, $2, ... auf die Teilstrings, die mit Klammern spezifiziert wurden zugreifen.
So werden im folgenden Beispiel die ersten drei Worte in der Ausgabe in der Reihenfolge vertaucht.
| Beispiel 6.1-10 | |
Verdeutlichen Sie sich das Zusammenwirken der Methoden von String() und RegExp() an Beispielprogrammen.