AA_schnipsel-karton_123rf-9152809_maurus.jpg

© maurus, 123rf.com

Schnipseljagd

Erste Schritte mit Regular Expressions

27.08.2011
Computer erleichtern die Arbeit – man muss ihnen nur genau sagen, was sie tun sollen. Mit regulären Ausdrücken beschleunigen Sie das Suchen und Ersetzen von Zeichenketten auf elegante Art.

Neben dem Übertragen und Darstellen von Daten zählt das Suchen und Ersetzen in Textstrukturen und Zeichenketten zu den häufigsten Aktionen beim Umgang mit dem Computer. Bei letzterem helfen die sogenannten regulären Ausdrücke (engl.: "regular expressions"). Deren Konzept umfasst einen komplexen Text- und Zeichenfilter, der ein ein effektives Suchen und Ersetzen in Zeichenketten jeglicher Form ermöglicht – etwa bei Strings in Programmiersprachen, in Ergebnissen von Datenbankabfragen und in Dokumenten als Dateien auf einem Datenträger.

Es spielt dabei keine Rolle, ob die Textdaten strukturiert vorliegen oder nicht – über Erfolg oder Misserfolg entscheidet nur die richtige Formulierung des regulären Ausdrucks (kurz auch Regex oder RE genannt). Allerdings fällt bei strukturierten Dokumentformaten wie CSV, HTML, XML, XSLT und LaTeX der Einsatz der REs meist leichter. Das Regex-Konzept ist weit verbreitet und zeichnet sich durch sehr hohe Stabilität aus. Für die Programmiersprachen Java, Perl, Python, PHP, Ruby, das .NET-Framework und für die Bash gehört es zum Standardumfang.

Die Beschreibung der gesuchten (Zeichen-)Muster folgt bestimmten syntaktischen Regeln, auch Grammatik genannt. Ein Programm wertet diese Grammatik aus und wendet sie auf eine Menge von Zeichen an. Der Rückgabewert umfasst eine Untermenge von Zeichen oder eine Trefferliste. Gibt es keine Übereinstimmung, bleibt diese Liste leer.

Reguläre Ausdrücke formulieren

Bei der Formulierung regulärer Ausdrücke gilt es generell zwei Punkte zu beachten: Erstens hilft es, wenn das Encoding für die Textdaten identisch mit dem des Regex ist. Anderenfalls müssen Sie Umlaute und Sonderzeichen im regulären Ausdruck für das Encoding der Textdaten anpassen. Der zweite Punkt betrifft die Eigenheiten der Regex-Implementierung in der gewählten Programmiersprache: Nicht alle Sprachen unterstützen den POSIX-Standard vollständig und definieren eigene Steuerzeichen.

Grundlagen

Sicherlich haben Sie schon einmal nach einer Person mit einem Namen gesucht, den es in unterschiedlich geschriebenen, aber phonetisch identischen Varianten gibt – etwa nach einem Meier, Schmidt oder Schulze [1]. Die folgenden Beispiele erläutern den Regex-Einsatz anhand dieses Problems. Als Adressbuch dient dabei eine Textdatei, in der Kommas die einzelnen Felder der Einträge trennen (Listing 1). Als Suchwerkzeug für die Kommandozeile kommt grep zum Einsatz.

Listing 1

Fritz Neunmalklug, Am Sterndamm 6, 12401 Berlin, 030 24 58 16
Joachim Mayer, 12 Rue de la Chapelle, CH-1002 Lausanne, 0041 21 67 23 69
Hans Fröhlich, Karlplatz 15, 51111 Köln, 0221 76 34 20
Horst Fischer, Rathausquai 78, 20165 Hamburg, 040 30 19 56 1
Klaus Meier, Mozartweg 7, 01256 Dresden, 0351 58 14 17
Holger maier, Kreuzgasse 15, 86161 Augsburg, 0821 50 23 19

Um Herrn Meier im Adressbuch zu finden, geben Sie Grep zwei Parameter mit: den Namen als Suchmuster und unser Adressbuch als Datei, in der Grep nachsehen soll (Listing 2, Zeile 1). Die Ausgabe umfasst nur eine einzige Zeile (Listing 2, Zeile 2).

Falls Sie sich nicht mehr genau daran erinnern können, ob sich der Gesuchte nun Meier oder Mayer schreibt, erweitern Sie den Grep-Aufruf kurzerhand um den passenden regulären Ausdruck (Listing 2, Zeile 4). Mit der Option -E behandelt Grep das Suchmuster als erweiterten Ausdruck und interpretiert die Steuerzeichen entsprechend. Die Klammern um ei gruppieren die beiden Zeichen e und i, der senkrechte Strich (|) fungiert als Oder-Operator für die beiden Gruppen (ei) und (ay). Die zusätzlichen Klammern um (ei)|(ay) sorgen dafür, dass Grep die beiden Gruppen als kompletten Unterausdruck auswertet.

Listing 2

$ grep Meier adressbuch
Klaus Meier, Mozartweg 7, 01256 Dresden, 0351 58 14 17
$ grep -E "M((ei)|(ay))er" adressbuch
Joachim Mayer, 12 Rue de la Chapelle, CH-1002 Lausanne, 0041 21 67 23 69
Klaus Meier, Mozartweg 7, 01256 Dresden, 0351 58 14 17
$ grep --color -i -E "M.{2}er" adressbuch
Joachim Mayer, 12 Rue de la Chapelle, CH-1002 Lausanne, 0041 21 67 23 69
Klaus Meier, Mozartweg 7, 01256 Dresden, 0351 58 14 17
Holger maier, Kreuzgasse 15, 86161 Augsburg, 0821 50 23 19

Den dritten Eintrag aus dem Adressbuch (Holger maier) unterschlägt Grep bislang, da der Familienname in der Adressdatei fälschlicherweise mit einem Kleinbuchstaben beginnt. Die Option -i ignoriert die Groß- und Kleinschreibung und fördert auch diesen Eintrag zutage.

Da wir aber auch wissen, dass "Meier" aus fünf Buchstaben besteht, vereinfachen wir den Grep-Aufruf so wie in Zeile 8 von Listing 2. Das Muster M.{2}er passt auf alle Zeichenketten, die mit einem M beginnen, gefolgt von zwei beliebigen, alphanumerischen Zeichen (.{2}) und mit der Buchstabenfolge er am Ende. Welche besonderen Zeichen in einem Muster welche Bedeutung haben, zeigt die Tabelle "Besondere Zeichen in regulären Ausdrücken".

Die Grep-Option --color erweist sich im Alltag als sehr nützlich: Sie hebt diejenigen Zeichen im Suchergebnis hervor, auf die das angegebene Muster passt (Abbildung 1) – in unserem Fall also die passenden Familiennamen.

Abbildung 1: Grep mit farbiger Hervorhebung des Suchergebnisses.

Besondere Zeichen in regulären Ausdrücken

Zeichen Bedeutung Beispiel Treffer bei
? vorhergehendes Element ist null oder ein Mal vorhanden (20)?11 2011, 11
+ mindestens eine Wiederholung des vorhergehenden Elements ab+ ab, abb, abbb, …
* keine, eine oder mehrere Wiederholungen des vorhergehenden Elements ab* a, ab, abb, abbb, …
| logisches Oder a|b a, b
. beliebiges einzelnes Zeichen Betr.g Betrag, Betrug, …
^ am Zeilenanfang ^Berlin Zeile beginnt mit Berlin
$ Zeilenende Berlin$ Zeile endet auf Berlin
[...] Bereich [a-fA-F] Zeichen a bis f und A bis F
[^...] Ausschlussbereich [^a-f] alle Zeichen außer a bis f
(...) gruppiert Elemente Loch(streifen|karte) Lochstreifen, Lochkarte
{x,y} Menge {Minimum, Maximum} \w{3,8} mindestens drei und maximal acht alphanumerische Zeichen
\w alphanumerische Zeichen (a-z, A-Z, 0-9 und _) \w+; \w+ zwei Worte, durch Semikolon und ein Leerzeichen voneinander getrennt
\s Leerzeichen (identisch zu \t\n\r\f) \w+\s+\w+ zwei Worte, durch mindestens ein Leerzeichen oder einen Tabulator getrennt
\d Ziffern (Grep: [0-9]) Zeile \d Zeile 0 bis Zeile 9
Um eines der besonderen Zeichen zu finden, müssen Sie es mittels Backslash escapen. Mit \. finden Sie beispielsweise einen Punkt.

Schlangenbeschwörung

Die Programmiersprache Python macht es Ihnen an vielen Stellen sehr leicht. Möchten Sie alle Varianten von Meier aus einer Namensliste herausfischen, dann kodieren Sie das wie in Listing 3 gezeigt. In Zeile 6 wird jeder Eintrag der Namensliste mit den möglichen Varianten verglichen und als Ergebnis lediglich Meier ausgegeben. Zu mayer gibt es keine exakte Entsprechung in der Variantenliste, weswegen Python diesen Eintrag nicht findet.

Listing 3

# -*- coding: utf-8 -*-
namensliste = ["Meier", "Müller", "Schulze", "mayer"]
variantenliste = ["Meier", "Meyer", "Maier", "Mayer"]
for eintrag in namensliste:
        if eintrag in variantenliste:
                print(eintrag)

Komfortabler funktioniert das Ganze mithilfe von Funktionen für Reguläre Ausdrücke. Diese stellt Python über das Modul re ([2],[3]) bereit – das Kürzel steht für "regular expressions". Dieses Modul wird in Listing 4 in der dritten Zeile deklariert, ab diesem Punkt lassen sich die Funktionen aus re im Skript nutzen. In Zeile 5 bereitet die Funktion re.compile() das Muster zunächst vor. Dabei steht im Muster [ae] für eines der Zeichen a und e, sinngemäß dasselbe gilt für [iy]. Das Caret (^) benennt den Wortanfang, das Dollarzeichen ($) das Wortende.

Listing 4

# -*- coding: utf-8 -*-
import re
namensliste = ["Meier", "Müller", "Schulze", "mayer"]
muster = re.compile('^m[ae][iy]er$', re.IGNORECASE)
for eintrag in namensliste:
        if muster.match(eintrag):
                print(eintrag)

Beim zweiten Parameter des Funktionsaufrufs handelt es sich um re.IGNORECASE, eine vordefinierte Konstante aus dem re-Modul. Sie bewirkt, dass beim Vergleich des Musters die Groß- und Kleinschreibung keine Rolle spielt. Die Funktion re.match() nimmt den Vergleich des Musters mit der Zeichenkette vor. Auf die Namensliste angewendet, erhalten Sie bei der Ausgabe in Zeile 8 sowohl Meier als auch mayer. Diese Variante deckt also alle acht möglichen Schreibweisen ab, ohne sie dazu wie in Listing 3 explizit aufzählen zu müssen.

LinuxCommunity kaufen

Einzelne Ausgabe
 
Abonnements
 

Ähnliche Artikel

  • Einfaches Erstellen von regulären Ausdrücken
    Wo reguläre Ausdrücke für den Profi ein Denksport sind, steht der Anfänger verzweifelt vor einem Dickicht an Kürzeln und Zeichen. Für den Durchblick sorgt der Editor txt2regex.
  • Zu Befehl
    Auch wenn sich viele Dinge bequem über grafische Oberflächen wie KDE oder GNOME regeln lassen – wer sein Linux-System richtig ausreizen möchte, kommt um die Kommandozeile nicht herum. Abgesehen davon gibt es auch sonst viele Situationen, wo es gut ist, sich im Befehlszeilendschungel ein wenig auszukennen.
  • Teil 3: String-Verarbeitung und Reguläre Ausdrücke
    Die Grundlagen der Zeichenketten haben wir in der letzten Ausgabe gelegt. Diesmal wollen wir uns aber nicht mit einfachen Leer-Tests oder Längenanzeigen begnügen, sondern unsere Strings kräftig durcheinander wirbeln.
  • Suchen und Finden mit Regulären Ausdrücken
    Zum wichtigsten Handwerkszeug bei der Suche in Texten und auf der Festplatte zählen Regular Expressions. Trotz ihrer scheinbar komplexen Struktur lassen sie sich schnell meistern.
  • sed
    Der Stream-Editor sed hilft beim automatischen Verändern einer oder mehrerer Dateien, vereinfacht sich wiederholende Änderungen oder erstellt gleich ganze Konvertierungsprogramme. Monotone Aufgaben der Textverarbeitung lassen sich so im Handumdrehen lösen.
Kommentare

Infos zur Publikation

title_2014_09

Digitale Ausgabe: Preis € 4,95
(inkl. 19% MwSt.)

Mit der Zeitschrift LinuxUser sind Sie als Power-User, Shell-Guru oder Administrator im kleinen Unternehmen monatlich auf dem aktuelle Stand in Sachen Linux und Open Source.

Sie sind sich nicht sicher, ob die Themen Ihnen liegen? Im Probeabo erhalten Sie drei Ausgaben zum reduzierten Preis. Einzelhefte, Abonnements sowie digitale Ausgaben erwerben Sie ganz einfach in unserem Online-Shop.

NEU: DIGITALE AUSGABEN FÜR TABLET & SMARTPHONE

HINWEIS ZU PAYPAL: Die Zahlung ist auch ohne eigenes Paypal-Konto ganz einfach per Kreditkarte oder Lastschrift möglich!       

Tipp der Woche

Schnell Multi-Boot-Medien mit MultiCD erstellen
Schnell Multi-Boot-Medien mit MultiCD erstellen
Tim Schürmann, 24.06.2014 12:40, 0 Kommentare

Wer mehrere nützliche Live-Systeme auf eine DVD brennen möchte, kommt mit den Startmedienerstellern der Distributionen nicht besonders weit: Diese ...

Aktuelle Fragen

Windows 8 startet nur mit externer Festplatte
Anne La, 10.09.2014 17:25, 4 Antworten
Hallo Leute, also, ich bin auf folgendes Problem gestoßen: Ich habe Ubuntu 14.04 auf meiner...
Videoüberwachung mit Zoneminder
Heinz Becker, 10.08.2014 17:57, 0 Antworten
Hallo, ich habe den ZONEMINDER erfolgreich installiert. Das Bild erscheint jedoch nicht,...
internes Wlan und USB-Wlan-Srick
Gerhard Blobner, 04.08.2014 15:20, 2 Antworten
Hallo Linux-Forum: ich bin ein neuer Linux-User (ca. 25 Jahre Windows) und bin von WIN 8 auf Mint...
Server antwortet mit falschem Namen
oin notna, 21.07.2014 19:13, 1 Antworten
Hallo liebe Community, Ich habe mit Apache einen Server aufgesetzt. Soweit, so gut. Im Heimnet...
o2 surfstick software für ubuntu?
daniel soltek, 15.07.2014 18:27, 1 Antworten
hallo zusammen, habe mir einen o2 surfstick huawei bestellt und gerade festgestellt, das der nic...