REGEX oder GREP
Reguläre Ausdrücke sind die Königsdiziplin der Textverarbeitung. Es gibt sie nicht nur in Javascript, sondern wir finden sie in nahezu allen Programmiersprachen. Reguläre Ausdrücke werden »Regex∑ abgekürzt oder auch "GREP" genannt. Sie wurden schon 1956 von Stephan Kleene entwickelt und 1968 von Ken Thompson für den Unix-Editor ED implementiert.
Um im Editor ED nach einem Textmuster zu suchen, gab man
g/Regular Expression/p ▲ ▲ ▲ | | | | Das Suchmuster Ende des regulären Ausdrucks | Anfang des regulären Ausdrucks
ein. Das g vor dem Schrägstrich bedeutet »Global«: Suche im gesamten Text. Darum wird die Suche mit regulären Ausdrücken auch GREP genannt. Und da Henry Spenver 1968 eine C-Library für Regular Expressions schrieb, ist die Suche mit Regex oder Grep in allen Programmiersprachen bis auf subtile kleine Unterschiede konsistent.
<div>
Bilder können data-URL-kodiert in PDF eingesetzt
werden, z.B. mit 300dpi oder 120dpi.
</div>
const text = document.querySelector("div").textContent;
console.log ("Treffer?" + /URL/.test(text));
Der Ausdruck nach dem wir suchen – URL – sitzt in "/". test () ist die Javascript-Methode, die prüft, ob der Ausdruck im Text vorkommt. Das einfachste aller Beispiele für Regex ist die wörtliche Suche. Allerdings würde /url/.test() nichts finden, denn Groß- / Kleinschreibung macht einen Unterschied.
Treffer? true
Für eine komplexere Suche verwendet Regex Metazeichen, also Platzhalter für eine Gruppe von Zeichen. So ist z.B. \d ein Metazeichen für irgendeine Ziffer, \d\d\d oder \d{3} für drei Ziffern in Folge. Der Backslash vor dem d kennzeichnet das d als Platzhalter für eine Ziffer, damit das d nicht als Buchstabe d gehalten wird. Dieses Schreibweise nennt man "escaping" (maskieren).
Metazeichen: der Punkt als Wildcard
Am einfachsten ist die literale (wörtliche) Suche: /auto/ findet auto und automatisch.
/go/i findet go in Logo, Gocart und in »Kaffee-to-Go«.
Durch das i (Ignore Case) nach dem schließenden Schrägstrich ignoriert der reguläre Ausdruck Groß- und Kleinschreibung.
Der Punkt "." ist das Wildcart-Zeichen in regulären Ausdrücken. Ein Punkt trifft jedes Zeichen außer Newline (Zeilenumbruch).
/lei.e/i findet Leiden, Leiter, leise, Schleife
Der Punkt als Wildcard ist gleichzeitig auch eine Falle, denn /3.00/ meldet einen Treffer in 3.00, 3900 und 3-00, obwohl wir nach 3.00 Uhr suchen.
Wenn also die Ziffer 3 gefolgt von einem normalen Punkt gefunden werden soll, wird der Punkt durch einen Backslash maskiert oder escaped:
/3\.00/ findet 3.00, aber nicht 3900 oder 3-00
/media\.de/ findet http://www.media.de
Basiszeichen
\d ist der Platzhalter für eine Ziffer, suchen wir nach 3 Ziffern in Folge, könnte man \d\d\d schreiben. Das hatten wir bereits. Weitere Basiszeichen stehen für Buchstaben, Weißraum und Sonderzeichen.
Metazeichen wie ^ und $ suchen am Anfang bzw. Ende eines Strings oder bieten Alternativen, wenn niemand weiß, ob mit Umlaut oder ohne: ä|ae.
Basiszeichen | |
---|---|
\w | Buchstabe, Ziffer oder Unterstrich |
\W | Ein Sonderzeichen |
\d | Eine Ziffer zwischen 0 bis 9 |
\D | Ein Zeichen, das keine Ziffer ist |
\s | Ein Weißraum (Leerzeichen, Zeilenumbruch usw.) |
\S | Jedes Zeichen außer Weißraum |
\b | Wortgrenze |
\B | keine Wortgrenze |
Metazeichen | |
---|---|
. | findet alle Zeichen außer Zeilenende |
^ | Anfang eines Strings |
$ | Ende eines Strings |
| | Alternativen |
() | Teile des Suchmusters abgrenzen |
[] | Zeichenklassen |
{} | Replikatoren |
/d hält für eine Ziffer her. Aber wenn nur Ziffern von 1 bis 4 vorkommen sollen? Das geht [1-4]. Äquivalent reagiert [A-D] nur auf Großbuchstaben A, B, C, D.
Die Replikatoren legen Wiederholungen fest. \w{3} steht für "mindestens 3 Zeichen".
Zeichenklassen | |
---|---|
[xyz] | beliebiger Buchstabe x, y oder z |
[^xyz] | jeder Buchstabe außer x, y oder z |
[0-9] | jede Ziffer zwischen 0 bis 9 |
[a-z] | jeder kleine Buchstabe von a bis z |
[A-Za-z0-9] | alle Buchstaben und Ziffern |
[a-zß-ü] | alle Kleinbuchstaben und Umlaute |
Replikatoren | |
---|---|
{n,m} | mindestens n mal, höchstens m mal |
{n,} | mindestens n mal |
{n} | genau n mal |
* | 0 mal oder öfter, äquivalent zu {0,} |
+ | 1 mal oder öfter, äquivalent zu {1,} |
? | 0 oder 1 mal, äquivalent zu {0,1} |
Kurzschreibweisen für Buchstaben, Ziffern und Leerzeichen
Die Basiszeichen suchen nach Buchstaben, Ziffern und Leerzeichen – teilweise sind sie eine Kurzschreibweise für Zeichenklassen. Groß- und Kleinschreibung unbedingt beachten!
- \w
- Findet alle Buchstaben, Zahlen und Unterstriche und kann auch durch die Zeichenklasse [a-zA-Z0-9_] dargestellt werden. Umlaute und ß hingegen zählen zu den Sonderzeichen.
- Suche nach allen Strings, die mit Ha anfangen, gefolgt von zwei beliebigen Buchstaben, Zahlen oder Unterstrichen gefolgt von einem o:
-
/ Ha \w \w o / g ▲ ▲ ▲ | | | | | +------> gefolgt von einem kleinen o | | | +------> gefolgt von zwei Buchstaben, Zahlen oder Unterstrichen | +------> Suchmuster beginnt mit Ha console.log (/Ha\w\wo/g.test('Hallo Hanno, hattest du Glück?')) true console.log ('Hallo Hanno! Hattest du Glück?'.match(/Ha\w\wo/g)) ["Hallo", "Hanno"]
- \W
- Findet alle Zeichen außer Buchstaben, Zahlen oder Unterstriche.
- Sucht nach allen Strings, die nicht mit einem Buchstaben, einer Zahl oder einem Unterstrich anfangen gefolgt von einem Leerzeichen.
-
/\W /g ▲▲ || |+------> gefolgt von einem Leerzeichen | +------> Erstes Zeichen ist weder Buchstabe, Zahl noch Unterstrich console.log('Hallo Hanno! Hattest du Glück?'.match(/\W /g)); ["! "]
- \d
- Findet alle Ziffern von 0 bis 9.
- Sucht Dateinamen, die mit DSC anfangen, gefolgt von vier Ziffern, gefolgt von .jpg oder JPG – ein Klassiker der Dateinamen aus Digitalkameras.
-
Muster: /dsc\d+.jpg/gi String: <img src="DSC4608.jpg"><img src="DSC4610.JPG"><img src="dsc4700.JPG"> console.log(string.match(/dsc\d+.jpg/gi)); ["DSC4608.jpg", "DSC4610.JPG", "dsc4700.JPG"] Beispiel: if (/\d+[\.|,]?\d*/.test(string)) ▲ ▲ ▲▲ ▲ ▲ │ │ ││ │ │ \d+: mindestens <-┘ │ ││ │ │ eine Ziffer │ ││ │ │ │ ││ │ │ \.: gefolgt von <---┘ ││ │ │ einem Punkt ││ │ │ ││ │ │ | oder <──────────┘│ │ │ ,: einem Komma <-──┘ │ │ │ └── d*: gefolgt von ?: Punkt oder Komma <---┘ 0 oder mehr Ziffern einmal oder keinmal
- \D
- Alle Zeichen, die keine Ziffern sind
- Sucht ebenfalls Dateinamen, aber diese Namen von Bilddateien aus der Digitalkamera beginnen mit einem Unterstrich. Gesucht werden TIFF-Dateien:
-
Muster: /\D{4}\d{4}\.tif/gi String: _DSC4608.tif oder _DSC4610.jpg oder _DSC4700.TIF oder _DSC4610.tif und ein Defekt: _DSC4611?tif Findet: _DSC4608.tif,_DSC4700.TIF,_DSC4610.tif
- \b
- Wortgrenze
- Testet, ob das class-Attribut eines HTML-Tags die Klasse showImg enthält:
-
Muster: /\bshowImg\b/ String: showImg2 content showImg Findet: liefert einen Treffer zurück
- \B
- Jede Position, die keine Wortgrenze ist
-
Muster: /\Bsee/gi String: See, Wannseebad, Nordsee Findet: See, Wannseebad, Nordsee
- \s
- Alle Whitespace-Zeichen – das sind alle Arten von Leerzeichen vom einfachen „Blank“ über Tabulatoren bis hin zum Zeilenumbruch.
- Eliminiert den Weißraum (Leerzeichen, Zeilenumbrücke, Tabulatoren) zwischen HTML-Tags:
-
Muster: />\s*</g // ersetzen durch >< String: <dt id="jsregSS">\s </dt> <dd>Alle Whitespace-Zeichen ….</dd> <dd>Findet den Weißraum zwischen HTML-Tags: </dd> Ersetzung: <dt id="jsregSS">\s </dt><dd>Alle Whitespace-Zeichen …</dd><dd>Findet den Weißraum zwischen HTML-Tags: </dd>
- \S
- Alle einzelnen Zeichen, die kein Whitespace sind.
-
Muster: /\Sa/gi String: Wandern andere „an“ Findet: Wandern andere „an“
Modifier g und i
Modifier sind der intuitivste Teil von regulären Ausdrücken. Modifier stehen am Ende des regulären Ausdrucks hinter dem schliessenden Begrenzer und legen globale Änderungen über den gesamten regulären Ausdruck.
In Javascript gibt es drei Modifier: g (global) veranlasst den Javascript-Interpreter, die Operation auf den gesamten String auszudehnen. Ansonsten sucht oder ersetzt der Interpreter nur erste Vorkommen des Suchmusters.
i (ignore case) schaltet die Unterscheidung zwischen Groß- und Kleinschreibung aus, die ansonsten der Standard ist.
m (multiline) findet Suchmuster am Anfang oder am Ende einer Zeichenkette. Der Modifier m wird ab Javascript 1.5 interpretiert.
Maskieren / Escaping
Metazeichen sind einfache Sonderzeichen wie ein Punkt und der senkrechte Strich, die in regulären Ausdrücken eine andere Bedeutung haben als in einem ganz normalen Suchstring.
Damit der reguläre Ausdruck ein Zeichen nicht als Sonderzeichen (hierzu zählen der Begrenzer / und auch der .), sondern als normales Zeichen auffasst, wird dem Zeichen ein umgekehrter Schrägstrich (Backslash) vorangestellt: /\// trifft das erste Vorkommen eines /-Zeichens und /\/\/www/ das erste Vorkommen von //www.
Das Leerzeichen ist nicht belegt und kann also ohne Maskierung in den regulären Ausdruck. Ein Tabulator hingegen wird als \t geschrieben.
Für Zeilenumbrüche gibt es gleich drei Möglichkeiten: \r (carrige return), \n (new line) und die Kombination \r\n. Welches Steuerzeichen angebraucht ist, hängt von dem Betriebssystem ab, auf dem es erzeugt wird.
Beispiele für reguläre Ausdrücke
- . (Punkt)
- findet alle Zeichen. Der Punkt erinnert an den *-Joker bei der Suche nach Dateinamen unter Windows und Mac. Im Gegensatz zu regulären Ausdrücken in Perl oder Grep findet der Punkt kein Zeilenende!
-
Muster: /./ String: James Bond Findet: J, a, m, e, s, , B, o, n, d String: \n\r Findet: kein Treffer
- ^ (Caret)
- steht für den Anfang eines Strings und darf nicht mit dem Caret-Zeichen verwechselt werden, das in eckigen Klammern eine Negierung bewirkt.
-
Muster: /^Von/ String: Von 3 bis 4, von 2 bis 5 Findet: Von 3 bis 4, von 2 bis 5
- $ (Dollar)
- kennzeichnet das Ende eines Strings und kann auch nur am Ende des regulären Ausdrucks vor dem schließenden Schrägstrich stehen.
-
Muster: /10$/ String: 10 vor 10 Findet: 10 vor 10 Muster: /^Martha$/ String: Unsere Martha Findet: kein Treffer
- | (Senkrechter Strich)
- Angabe von Alternativen
-
Muster: /H(ä|ae)(ß|ss)ler/g // Sucht unterschiedliche Schreibweisen String: Ulrike Häßler Ulrike Haessler Ulrike Haeßler Findet: Häßler,Haessler,Haeßler
- () (runde Klammern)
- Ein Ausdruck in runden Klammern fasst Teile des Suchmusters zusammen und grenzt es von anderen Suchmustern ab. Ausdrücke in runden Klammern bilden Unterausdrücke, die sich später durch sogenannte Rückverweise (Backreference) ansprechen lassen. Rückverweise in regulären Ausdrücken erlauben z.B. den Tausch der Position von Strings.
-
Muster: /Ann (H|M)/g String: Ann H., Ann M., Ann S. Findet: Ann H., Ann M., Ann S. Muster: /(a|b)(c|d)/ Findet: alle Zeichenketten ac, ad, bc oder bd Muster /(A(b|c)|DEF)/ Findet: alle Zeichenketten Ab, Ac oder DEF
- [ ] (eckige Klammern)
- grenzt eine Liste von Zeichen an einer bestimmten Position der Zeichenkette weiter ein.
-
Muster: /S[abc]/g String: Sache, Sinn, Schaden Findet: Sache, Sinn, Schaden
Zeichenklassen
Viereckige Klammern legen eine Zeichenklasse fest. Eine Zeichenklasse steht an ihrer Position im String für eine Gruppe von Zeichen – z.B. legt S[a-h] fest, dass an der Stelle hinter dem S ein Buchstabe von a bis h stehen muss.
Innerhalb der viereckigen Klammern verlieren alle Metazeichen außer dem Circumflex und dem Backslash ihre Bedeutung und müssen nicht maskiert werden. Der Circumflex am Anfang einer Zeichenklasse negiert die Zeichen – S[^a-e] legt fest, dass nach dem großen S kein Buchstabe aus dem Bereich a bis e stehen darf. Steht der Circumflex nicht am Anfang der Zeichenklasse – S[a-e^] – verliert er seine besondere Bedeutung und hier wird nach dem großen S gefolgt von einem Buchstaben von a bis e oder einem Circumflex gesucht.
- [xyz]
- Findet alle Zeichen innerhalb der eckigen Klammern.
- Sucht nach Zeichenketten, die ein D oder ein R an der zweiten Stelle aufweisen
-
Muster: /w[DR]\w/g ▲ ▲ ▲ │ │ │ │ │ └ \w: gefolgt von einem beliebigen Buchstaben │ │ │ └ [DR]: gefolgt von D oder R │ └ \w: Beliebiger Buchstabe String: ARD, WDR, RTL, PRO7, MDR, BR Findet: ARD,WDR,PRO,MDR
- [^xyz]
- Der Circumflex innerhalb einer Zeichenklasse grenzt eine Liste von Zeichen an einer bestimmten Position der Zeichenkette aus.
- Sucht nach allen Zeichenketten, die mit S beginnen und an der zweiten Stelle kein a, b oder c enthalten:
-
Muster: /S[^abc]\w*/g ▲ ▲ ▲ ▲ │ │ │ │ S: Buchstabe S ─────┘ │ │ │ │ │ │ [^abc]: nicht gefolgt ┘ │ │ von a, b, oder c │ │ │ │ \w: gefolgt von einem ──────┘ │ beliebigen Buchstaben │ │ *: vorangehendes Zeichen ────┘ darf beliebig oft vorkommen String: Sinn, solche Sachen, so ein Schaden, Sonderfall, Sonne und Regen Findet: Sinn,Sonderfall,Sonne
- [a-z]
- Alle Zeichen von a bis z.
- Sucht alle Wörter, die mit T oder t anfangen und einen Bindestrich enthalten können:
-
Muster: /\bT[a-zß-ü-]*/gi String: Tor T-Shirt Torbögen, der junge Törleß Torwart Torè Toraç Torø Findet: Tor,T-Shirt,Torbögen,Törleß,Torwart,Torè,Toraç,Torø
- [0-9]
- Alle Ziffern von 0 bis 9
- Sucht alle Zahlen am Anfang einer Zeile, die mit 5 anfangen
-
Muster: /^5[0-9]*/gm ▲▲ ▲ ▲ ▲▲ ^: Anfang der -┘│ │ │ │└ m: in jeder Zeile Zeichenkette │ │ │ │ │ │ │ └ g: im gesamten String 5: Erstes Zeichen ┘ │ │ ist eine 5 │ │ │ │ [0-9]: gefolgt von ┘ │ einer Ziffer von │ 0 bis 9 │ │ *: vorangehendes Zeichen ┘ darf beliebig oft vorkommen String: 50074 Irgendwo 2750 Zinnsoldaten 59245 Leitzahl 5 oder 5700 Findet: 50074,59245,5
- [A-Za-z0-9]
- alle Buchstaben und Ziffern, aber keine Umlaute
- [a-zß-ü]
- alle Kleinbuchstaben und kleinen Umlaute
- [A-ZÀ-Ü] sucht nach allen Großbuchstaben und großen Umlauten und erwischt neben den Umlauten der deutschen Sprache auch die groß geschriebenen Ç, É und Õ.
Umlaute haben ein schweres Leben in regulären Ausdrücken. Wunderbarer Weise erwischt ß-ü das ß und alle Umlaute der deutschen Sprache sowie das Accent Egue der Franzosen, die Ligatur æ und ein Cedilla, äquivalent dazu liefert À-Ü die groß geschriebenen Umlaute der westeuropäischen Zeichen.
Replikatoren
Replikatoren legen minimale, maximale oder exakte Anzahlen für ein oder mehrere Zeichen fest. Ohne die Angabe von Replikatoren nimmt der Javascript-Interpreter an, dass ein Zeichen genau einmal vorkommen muss.
- {n}
- Das vorangestellte Zeichen muss genau n mal vorkommen
- Muster: /20{3}/
- Treffer: 2000 und 2004
- {n,}
- Steht für eine Anzahl von mindestens n Zeichen
- Muster: /^[0-9]{5}$/ String: 57366 Findet: 57366
- {n,m}
- Steht für eine Anzahl von mindestens n, aber höchstens m Zeichen.
-
Muster: /_DSC\d{4}.TIF/i String: _DSC4608.tif _DSC4610.tif _DSC4700.TIF Findet: _DSC4608.tif,_DSC4610.tif,_DSC4700.TIF
- ?
- Das vorangestellte Zeichen darf genau null mal oder einmal in der Zeichenkette vorkommen.
- Muster: /\D?\d{6}/g findet in einem Nummerkreis aus sechs Ziffern, in dem Ziffern ein Buchstabe vorangestellt sein kann
- Treffer: D100345, 2000, 234567, D18254, 1234
- *
- Das vorangestellte Zeichen kann 0 mal oder beliebig oft vorkommen. Mit großer Vorsicht zu verwenden: /a*/ trifft auf jeden String zu, denn ein a ist immer drin oder nicht drin.
- Muster: /a*/
- Treffer: Dunkelheit und Sonnenschein
- +
- Das vorangestellte Zeichen muss mindestens einmal, kann aber auch mehrmals vorkommen.
- Sucht nach allen Tags und ersetzt sie durch einen Leerstring "":
-
Muster: /<[^<]+</g | | || <: Zeichenkette beginnt mit < <------+ | || | || [^<]: Alle Zeichen außer < <------+ || || +: vorangestelltes Zeichen ([^<]) muss mind. einmal vorkommen <------+| | <: Zeichenkette ende mit < <------+ String: <dl> <dt id="jsregUmlaute">[a-zß-ü]</dt> <dd>alle Kleinbuchstaben und kleinen Umlaute</dd> <dd>[A-ZÀ-Ü] sucht nach allen Großbuchstaben und großen Umlauten</dd> </dl> <p>Umlaute haben ein schweres Leben.</p> Ersetzung: [a-zß-ü] alle Kleinbuchstaben und kleinen Umlaute [A-ZÀ-Ü] sucht nach allen Großbuchstaben und großen Umlauten Umlaute haben ein schweres Leben.
- Auf diesselbe Weise werden Hochkommas gesucht: /"[^"]+"/g