Aus LinuxUser 08/2005

Suchen und Finden mit Regulären Ausdrücken (Seite 2)

$ egrep -i 'Ha[mr]burg' stadtliste.txt
Hamburg
Harburg

Ausformuliert bedeutet dieser Regex: Die Zeichen H, a, gefolgt von einem m oder r, gefolgt von b, u, r, g. Wollem Sie nun auch noch Bad Homburg suchen, müssen Sie den Ausdruck etwas erweitern zu: H[ao][mr]burg. Dieser Regex würde zusätzlich einen weiteren Ort finden, wenn er in der Liste existierte. Erraten Sie, welchen? Kleiner Tipp: Er liegt in Niedersachsen.

Statt einzelner erlaubter Zeichen können Sie mit dem Minuszeichen (-) auch einen Zeichenbereich angeben. Dies stellt insbesondere dann eine Erleichterung dar, wenn aufeinander folgende Zeichen wie A-Z oder 0-9 gemeint sind. Stellen Sie sich vor, Sie müssten [ABCDEF...Z] tippen! [A-Z] sieht doch wesentlich entspannter aus.

Als Beispiel können Sie eine HTML-Datei betrachten, in der Sie nach allen Header-Tags suchen wollen (also <H1>, <H2>, <H3>, <H4>). Der Regex dazu lautet: H[1-4]. Das ist gleichbedeutend mit, aber wesentlich kürzer als H[1234].

Zeilenanfang und Zeilenende

Als nächstes wollen wir alle Städte auflisten, die den Titel „Bad“ führen dürfen. Bei der Eingabe des naheliegenden Befehls erhalten wir aber:

<B>$ egrep -i 'Bad' stadtliste.txt<B>
Bad Homburg
Bad Nauheim
Friedrichsbad
Baden-Baden

Obwohl Friedrichsbad bestimmt wunderschön ist (falls es überhaupt existiert), erfüllt es doch nicht unsere strengen Bedingungen. Das Problem lässt sich auf zwei Arten lösen: Erstens könnten Sie auf den Schalter -i verzichten, dann würde Egrep explizit nach einem großen ‚B‘ suchen. In dem Fall hätten Sie das Problem dann aber nicht mit einem Regex gelöst, sondern mit den Bordmitteln von egrep.

Zweitens könnten Sie angeben, dass das ‚B‘ unmittelbar am Anfang der Zeile stehen muss. Damit würde Friedrichsbad nicht mehr angezeigt werden. Das hierfür verwendete Metazeichen ist das Hochzeichen ^. Der korrekte Regex für diese Aufgabe lautet demnach ^Bad.

Ein Versuch zeigt, dass bei einem Aufruf mit diesem Regex Friedrichsbad zwar aus der Ausgabe verschwindet, Baden-Baden aber noch immer erscheint. Der Reguläre Ausdruck arbeitet also noch nicht ausreichend präzise. Das Merkmal, das „Bad XXX“ deutlich von „Baden-Baden“ unterscheidet, ist das auf das d folgende Leerzeichen. Praktischerweise handelt es sich beim Leerzeichen ebenfalls um ein ganz normales Zeichen, das in einem Regex vorkommen darf. Erweitern Sie den Regulären Ausdruck also zu '^Bad ' (nun mit Leerzeichen hinter dem d), geht nichts mehr schief:

<B>$ egrep -i '^Bad ' stadtliste.txt<B>
Bad Homburg
Bad Nauheim

Auf ähnlichem Weg können Sie auch das Zeilenende näher spezifizieren. Möchten Sie also erreichen, dass Hamburg, nicht aber Burgwedel angezeigt wird, formulieren Sie: burg$. Das bedeutet soviel wie: Auf die Zeichen B, u, r, g muss das Zeilenende folgen.

Alles, nur nicht das!

Eine Sonderform der bisher besprochenen Metazeichen stellt die Ausschlussliste dar. Taucht das Hochzeichen (^) innerhalb einer Zeichenklasse auf, verneint es sie und gibt somit an, welche Zeichen nicht vorkommen dürfen. Wollen Sie beispielsweise keine Städte anzeigen, die mit B, H oder I beginnen, müssen Sie angeben, dass auf den Zeilenanfang keiner der drei Buchstaben folgen darf:

<B>$ egrep -i '^[^BHI]' stadtliste.txt<B>
München
Frankfurt
Friedrichsbad

Noch einmal zum Mitdenken: Zeilenanfang ^, nicht gefolgt ([^) von B oder H oder I (BHI]).

Beliebige Zeichen

Ein sehr einfaches, aber dennoch nützliches Metazeichen ist der Punkt .. Er bezeichnet „irgendein Zeichen“. Sie wissen ja, dass in Deutschland Dezimalzahlen mit Komma dargestellt werden. Pi schreibt sich also hierzulande 3,1415. Im Englischen gilt allerdings die Notation: 3.1415. Um beide Fälle mit einer Zeichenklasse abzufangen, müssten Sie 3[.,]1415 formulieren. Sie können aber auch 3.1415 als Regex verwenden: Hier heißt das dann nicht: Die Zeichen 3, ".", 1, 4, 1, 5, sondern: Das Zeichen 3, gefolgt von irgendeinem Zeichen, gefolgt von 1, 4, 1, 5.

Die Alternation

Als Beispiel für die Alternation, die nicht mehr auf einzelnen Zeichen oder einem Zeichenbereich basiert, sondern feste Zeichenketten beliebiger Länge unterscheidet, sollen uns die beiden Orte Idstedt (in Schleswig-Holstein) und Idstein (in Hessen) dienen. Mittels einer Zeichenklasse können Sie zwar einenentsprechendenn Regex formulieren, der bei beiden Städten einen Treffer erzeugt: Idste[id][nt]. Doch gibt es hier ein Problem: Idste[id][nt] findet auch „Idstedn“ und „Idsteit“. Dies ist bei der Alternation ausgeschlossen:

LinuxUser 08/2005 KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS
Deutschland

Hinterlasse einen Kommentar

  E-Mail Benachrichtigung  
Benachrichtige mich zu: