Javascript • Reguläre Ausdrücke – Suchen und Ersetzen

Javascript Reguläre Ausdrücke – Regex

Reguläre Ausdrücke suchen mit einem Muster oder Pattern von Platzzeichen nach Zeichenfolgen – z.B. »Suche alle Wörter, die mit einem großen D anfangen und mehr als drei Buchstaben haben« oder »Ist diese Zeichenfolge eine richtige Postleitzahl?«.

23-02-02 SITEMAP CSS HTML JS Basis JS Web Tutorial SVG

REGEX oder GREP

Regex sind die Königsdiziplin der Textverarbeitung. Es gibt sie nicht nur in Javascript, sondern wir Regex 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>

let 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
\wBuchstabe, Ziffer oder Unterstrich
\WEin Sonderzeichen
\dEine Ziffer zwischen 0 bis 9
\DEin Zeichen, das keine Ziffer ist
\sEin Weißraum (Leerzeichen, Zeilenumbruch usw.)
\SJedes Zeichen außer Weißraum
\bWortgrenze
\Bkeine 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 .tif oder TIF – 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  <---+ | |
                                          | |
    ?: Punkt oder Komma dürfen einmal <---+ |
       oder keinmal auftreten               |
                                            |
    d*: gefolgt von 0 oder mehr Ziffern <---+
\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:                                     /<[DR]\w/g
                                             |  |  |
             \w: Beliebiger Buchstabe <------+  |  |
                                                |  |
              [DR]: gefolgt von D oder R <------+  |
                                                   |
\w: gefolgt von einem beliebigen Buchstaben <------+ 

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 Zeichenkette <------+|  |  | ||
                                                      |  |  | ||
                  5: Erstes Zeichen ist eine 5 <------+  |  | ||
                                                         |  | ||
      [0-9]: gefolgt von einer Ziffer von 0 bis 9 <------+  | ||
                                                            | ||
*: vorangehendes Zeichen darf beliebig oft vorkommen <------+ ||
                                                              ||
                                 g: im gesamten String <------+|
                                                               |
                                      m: in jeder Zeile <------+
String: 50074 Irgendwo
        2700 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