Webdesign mit CSS, HTML und Javascript
Stil mit {stil}
![]() Die Abkürzungen der Objektive foto.5lux.de Online-Magazin für Fotografie und Bildbearbeitung |
Jan 2009
Reguläre Ausdrücke – Regex – mit Javascript
Seit Version 1.2 unterstützt Javascript reguläre Ausdrücke. Reguläre Ausdrücke prüfen Benutzereingaben, stellen fest, ob eine Zeichenkette eine Emailadresse darstellt und verhindern, dass Benutzer HTML-Tags in das Eingabefeld eines Formulars schreibt.
Reguläre Ausdrücke können in den folgenden String-Funktionen verwendet werden:
- match()
- replace()
- search()
- split()
Neben den Methoden des String-Objekts gibt es die Methoden des RegExp-Objekts
- compile()
- exec()
- test()
Reguläre Ausdrücke werden von ihren Anhängern auch "Regex" genannt und sind aus dem Schatzkästchen der Programmiersprache Perl entliehen. Regex sind das Werkzeug für die Mustererkennung und -ersetzung auf der Kommandozeile und in Programmiersprachen wie Perl, PHP und Javascript.
Using Regular Expressions with JavaScript and ECMAScript
Vergleichen mit match()
Die String-Methode match() durchsucht den String nach allen Vorkommen des Suchmusters und gibt ein Array mit den Treffern zurück. Bei literalen Strings mag das nicht besonders nützlich sein (wenn z.B. Tor in „Es war eine Tortur für den Torwart“ gesucht wird, lautet das Array anschliessend Tor, Tor), aber ein regulärer Ausdruck kann alle Strings sammeln, die mit Tor beginnen.
Alle Zeichenketten, die mit Tor oder tor anfangen
/\bTor\w*/gi
^ ^ ^ ^ ^^^
Begrenzer ——————+ | | | |||
| | | |||
Wortgrenze ——————+ | | |||
| | |||
Zeichenfolge Tor ——————+ | |||
| |||
gefolgt von bel. vielen Buchstaben oder Ziffern ——————+ |||
|||
Begrenzer ——————+||
||
g: im gesamten String ——————+|
|
i: ignore case ——————+
if (simpleString.match(/\bTor\w*/gi)) {
var treffer = simpleString.match(/\bTor\w*/gi);
alert("Gefunden: " + treffer.length + " " + treffer);
} else {
alert('Nicht enthalten');
}
// Ausgabe
// Gefunden: 6
// Tor,Torwart,Torbogen,Tortur,Torte,Torsten
Suchen und Ersetzen: replace(r, s)
Die String-Methode replace() ersetzt alle Vorkommen eines Strings oder regulären Ausdrucks r durch den String s im zweiten Parameter und gibt den geänderten String zurück.
var newString = simpleString.replace(/\bTor\w*/gi, "***");
alert(newString);
// Ausgabe: *** und ***, *** und ***, *** und ***
ersetzt alle Zeichenketten im String simpleString, die mit Tor oder tor anfangen, durch "***".
stripTags
Auch stripTags ist eine nützliche PHP-Funktion, die in Javascript nicht angeboten wird. striptTags extrahiert alle HTML-Tags aus einem String.
String.prototype.stripTags = function() {
var matchTag = /<(?:.|\s)*?>/g;
return this.replace(matchTag, "");
};
var main = document.getElementById("main");
var strippedText = main.innerHTML.stripTags();
Trennen: split(r)
Die String-Methode split() teilt einen String anhand des Suchmusters r in Unterstrings und gibt ein Array der Unterstrings zurück. Der Suchstring oder der reguläre Ausdruck bilden beim Aufruf von split() also das Trennzeichen, das bei der Operation aus dem String entfernt wird.
/:|,|#/g
^^^^^^^^
||||||||
Begrenzer ------+|||||||
Suchmuster Doppelpunkt ------+||||||
oder ------+|||||
Suchmuster Komma ------+||||
oder ------+|||
Suchmuster Hash-Zeichen ------+||
Begrenzer ------+|
global im gesamten String ------+
var treffer = simpleString.split(/:|,|#/g);
alert(treffer);
Ausgabe: Donald Duck,,Micky Mouse,Popey der Seemann,Lucky Luke
Das doppelte Komma nach Donald Duck ist ein leeres Array-Element, das durch den Doppelpunkt nach Donald Duck entsteht. split() ist also beim Import aus Word oder CVS-Dateien die Methode der Wahl.
Entwickeln: compile()
Beschleunigt die Auswertung des regulären Ausdrucks regex, wenn der Ausdruck z.B. während der gesamten Ausführung oder in einer while-Schleife konstant bleibt.
regex.compile(/\b((H(ae|ä)(ss|ß)ler)|(Meier))\b/gi)
Suchen: search(r)
Die String-Methode search() ist der Methode match() sehr ähnlich, gibt aber anstelle eines Arrays mit den Treffern die Position des ersten gefundenen Substrings zurück oder -1, wenn kein Treffer existiert.
Sucht die erste fünfstellige Zahl, die mit einer 2 beginnt:
/2\d{4}/
^^^ ^ ^
||| | |
Begrenzer ------+|| | |
Erstes Zeichen muss eine 2 sein ------+| | |
gefolgt von einer beliebigen Ziffer \d ------+ | |
gefolgt von genau 4 Ziffern ------+ |
Begrenzer ------+
if (simpleString.search(/2\d{4}/) == -1) {
alert("Suchmuster nicht gefunden")
} else {
var pos = simpleString.search(/2\d{4}/);
alert("Suchmuster gefunden an Position " + pos);
}
Reguläre Ausdrücke deklarieren
RegExp ist der Prototyp für reguläre Ausdrücke. Zwei Methoden stehen zur Konstruktion von regulären Ausdrücken zur Verfügung: die Deklaration als literaler Ausdruck und der Aufruf der Konstrukturfunktion.
Methode 1: Durch ein Literal
Jeder Javascript-Thread (ein Fenster) enthält ein vor-initialisiertes RegExp-Objekt. Die einfachste Technik, einen neuen regulären Ausdruck zu deklarieren, ist
var regex = /ab+c/gim;
Schrägstriche / / begrenzen reguläre Ausdrücke anstelle der Hochkommas " " und ' ', die ganz normale Strings eingrenzen. Die optionalen Modifier g (global, im gesamten String), i (in sensitive, Groß- und Kleinschreibung) und m (multiline – seit Javascript 1.5) stehen direkt und ohne Leerzeichen nach dem schließenden Schrägstrich.
Der Javascript-Interpreter übersetzt literale reguläre Ausdrücke, wenn das Script evaluiert wird. Wenn der reguläre Ausdruck konstant bleibt, ist ein literaler regulärer Ausdruck schneller.
Methode 2: Aufruf der Konstruktorfunktion
Die Konstruktor-Funktion empfiehlt sich, wenn sich das Suchmuster des regulären Ausdrucks ändert, wenn das Muster nicht bekannt ist und z.B. aus einem Eingabefeld stammt. Der Ausdruck wird zur Laufzeit ausgewertet.
var regex = new RegExp("ab+c");
Im zweiten optionalen Argument stehen die Modifier:
var regex = new RegExp ("ab+c", "g");
Wichtig: Die Konstruktorfunktion verwendet Hochkammas sowohl für den regulären Ausdruck als auch für die optionalen Modifier. Die eingrenzenden Schrägstriche entfallen und ein Schrägstrich muss nicht maskiert werden.
Das regExp-Objekt weist neun Speicherstellen und die Methoden regex.compile, regex.test und regex.exec auf. Dazu muss das reguläre Objekt aber nicht über new angelegt werden, sondern kann als einfache Variable definiert werden – diese besitzt trotzdem die Funktionalität des Objekts.
$1 … $9 Speicherslots eines regulären Ausdrucks
Ausführen eines Suchmusters: exec(s)
Führt einen regulären Ausdruck auf eine Zeichenkette s aus und gibt detallierte Informationen zu den Treffern sowie die Treffer der Unterausdrücke in runden Klammern zurück – wenn nur ein einfacher Test durchgeführt werden soll, ob der Ausdruck in einem String vorkommt, ist die test-Methode schneller.
// Findet alle Worter, die mit d, D, e, E, F oder f anfangen
var regex = /\b(d|e|f)\w*\b/gi;
var matches = regex.exec(simpleString);
if (matches === null) {
alert('Kein Treffer');
} else {
alert("Informationen zum regulären Ausdruck \n" +
"lastIndex " + regex.lastIndex + "\n" +
"ignoreCase " + regex.ignoreCase + "\n" +
"global " + regex.global + "\n" +
"source " + regex.source + "\n\n" +
"Informationen zum extrahierten String \n" +
"Rückgabewert " + matches + "\n" +
"Erstes Element matches[0] " + matches[0] + "\n" +
"Zweites Element matches[1] " + matches[1] + "\n" +
"index " + matches.index + "\n" +
"input " + matches.input);
}
return false;
}
Vergleichen mit test()
Die Methode test wird auf den String angewendet.
if (regEx.test(entryValue)) {
/* Gefunden! */
}
Backreferences – Informationen zu letzten erfolgreichen Treffer
Aufrufe der Methoden exec(), match(), test(), search(), replace() und split() ändern das globale RegExp-Objekt.
Das globale RegExp-Objekt beherbergt Eigenschaften, die nützliche Informationen über den letzten erfolgreichen Teffer bieten.
| Eigenschaft | Beschreibung |
RegExp.$1 | Nur lesen -- Neun Slots für Ausdrücke in runden Klammern. Die Zahl der Substrings in runden Klammern kann zwar beliebig groß sein, aber das RegExp-Objekt bietet nur diese neun Plätze. |
RegExp.index | Nur lesen -- Anfang des ersten erfolgreichen Treffers im durchsuchten String |
RegExp.lastIndex | Nur lesen -- Anfang des letzten erfolgreichen Treffers im durchsuchten String |
RegExp.input | Nur lesen -- enthält den durchsuchten String. |
RegExp.lastMatch | Nur lesen that holds the substring matched by the last successful pattern match. |
RegExp.lastParen | A read-only property that specifies the last parenthesized substring match, if any. |
RegExp.leftContext | A read-only property that specifies the string preceding whatever was matched by the last successful pattern match. |
RegExp.multiline | A read-only Boolean property that reflects whether or not to search strings across multiple lines. In Navigator, you can also assign a value to this property. The use of this variable in Perl is now deprecated, because the /m modifier is supported. This property only influences the interpretation of ^ and $ in a regular expression. |
RegExp.rightContext | A read-only property that specifies the string following whatever was matched by the last successful pattern match. |
Zeilenumbrüche suchen
Anders als in Python und Perl, wo Flags das Verhalten des Punkt-Zeichens ändern können, findet der Punkt "." in einem regulären Ausdruck in Javascript Neue Zeile nicht. Wenn die Neue Zeile gesucht wird, kann man statt des Punktes die Zeichenklasse [\s\S] (was soviel wie „jedes Zeichen, dass entweder ein Whitespace oder kein Whitespace ist“) suchen.
MS Word – HTML aus Word in valide Dokumente umwandeln
Wenn Word-Dokumente als HTML-Dokumente gespeichert werden, füllt Microsoft das HTML mit einer Vielzahl von überflüssigen und herstellerspezifischen Stilen und bedingten Kommentaren.
Für das Suchen und Ersetzen von style-Attributen:
/\S\s/{+}
Zeilenumbrüche normalisieren
Unix und Windows haben verschiedene Zeilenumbrüche: Unix und Mac OS X verwenden \n, Mac OS Roman verwendet \r, Windows verwendet \r\n. Wenn z.B. Zeilenumbrüche aus einem Eingabefeld in <br />-Tags umgewandelt werden sollen (ähnlich der Funktion nl3br in PHP), normalisiert man sie mit einem regulären Ausdruck:
var htmlString = myString.replace(/(\r\n)|(\r)/g, '<br />');
Postleitzahlen
var myString = "47226";
var muster = /^[0-9]{5}$/;
var matches = myString.match(muster);
if (!matches) {
alert('Keine Postleitzahl')
}
URLs und Dateien
Die Validierung einer URL erfordert häufig eine bestimmte Namenserweiterung. Ein regulärer Ausdruck, der alle Dateinamen "erwischt", ist:
- /^\S+\.(gif|jpg|jpeg|png)$/
Der reguläre Ausdruck findet die Standard-Namen für Bilder. Narrensicher ist der Ausdruck zwar nicht, aber er validiert Ordnernamen wie a//b.gif und Pfadangaben wie a:/b:/c.gif
Emailadressen
Eine eMail-Adresse darf nur aus Buchstaben, Ziffern, Bindestrichen, Unterstrichen, Punkten und einem "@" als Trenner bestehen. Die Toplevel-Domains sind ebenfalls festgelegt. Emailadressen haben die Form xxx@yyy, wobei xxx die Mailbox (die Unterstriche und Punkte enthalten kann) und yyy den Domainnamen mit einem Suffix wie .de oder .org darstellt. Ein regulärer Ausdruck, der fast alle validen Zeichenfolgen für Emailadressen einfängt, ist:
/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,4})+$/
Jetzt geben wir ein Muster für den Namen der Mailbox an, der Punkte und Bindestriche enthalten kann, aber mit einem oder mehreren alphanumerischen Zeichen \w+ beginnen muss. ([\.-]?\w+)* erlaubt beliebig viele Punkte oder Bindestriche; das \w+ em Ende stellt sicher, dass weder Punkte noch Bindestriche am Ende des Namens auftreten. Das Zeichen @ ist erforderlich.
Der Domainname kann mehrere .xx oder .xyz wie .de.org enthalten. Ein einmaliges \w+ stellt sicher, dass der Domainname mit alphanumerischen Zeichen beginnt und ([\.-]?\w+)* erlaubt Vorkommen von Bindestrichen und Punkten. Am Ende stellt (\.\w{2,3})+ sicher, dass mindestens ein Suffix aus einem Punkt gefolgt von zwei bis vier Zeichen aufgeführt ist.
Note: Das Suchmuster ist nicht wirklich narrensicher, da die neuen Domainnamen mit mehr als vier Zeichen nicht abgefangen werden. Außerdem sind nicht alle Kombinationen aus zwei oder drei Buchstaben legitime Domainen.
