Reguläre Ausdrücke (RE, Regular Expressions) wurden von 1956 S.C. Kleene eingeführt und sie erwiesen sich als sehr effektiv, um Zeichenketten zu beschreiben.
REs werden dann verwendet, wenn man die Form einer Zeichenkette (String) angeben will - sie beschreiben also Klassen von Strings. Es ist zum Beispiel einfacher die Form der natürlichen Zahlen als "eine Zeichenkette, bestehend aus einer oder mehreren Ziffern aus der Menge {0,1,2,3,4,5,6,7,8,9}" zu definieren, als alle Zahlen von 0 bis unendlich aufzuzählen. Reguläre Ausdrücke sind eine Schreibweise, mit der man solche Klassen eindeutig beschreiben kann.
Man sagt eine RE passt auf eine Zeichenkette, wenn diese in der von der RE umrissenen Klasse enthalten ist. Häufig werden REs verwendet, um aus einem String einen Teilstring heraus zu picken, welcher von der RE beschrieben werden kann. Dabei gilt das Prinzip der längsten Übereinstimmung (longest match), was heißen soll dass dies der längste Teilstring ist, auf den die RE passt. In diesem Zusammenhang spricht man auch davon, REs sind greedy.
Tabelle 1. Erweiterte Reguläre Ausdrücke (Extended Regular Expressions)
Für detailliertere Informationen siehe die man-page regex(7) oder,
falls nicht vorhanden die man-page zu awk(1), welche lange Zeit auch als die Referenz für REs galt,
oder flex(1) oder die
Online-Dokumentation der Open Group.
(x|y|z) ist äquivalent zu [xyz] und (a|b) ist
äquivalent zu (b|a).
Die RE (B|Dr)al{2} passt sowohl auf "Ball" als auch auf "Drall".
Die RE ^#.* passt auf alle Zeilen, die mit einem '#' anfangen.
Ist die RE ^# äquivalent zur vorhergehenden?
Zur reinen Mustersuche passen beide REs auf die selben Zeilen, der Unterschied kommt dann zu Tage,
wenn man die gefundenen Muster weiterverarbeiten will.
Erstere RE benennt die ganze Zeile, vom Beginn bis zum newline,
zweitere benennt nur das Zeichen '#' am Anfang der Zeile.
Eine Gleitkommazahl wie 3.675E-15 kann man mit [[:digit:]]+\.[[:digit:]]*([eE][+-]?[[:digit:]]+)? beschreiben.
Zu beachten ist der Backslash '\' vor dem Punkt, da jener eine Sonderbedeutung hat, die mit dem vorangestellten '\' unterbunden wird.
Leider hat diese Beschreibung einen Nachteil: sie lässt zwar die Zahl 1. durch, verbietet aber die Zahl .1,
also noch einmal: (([[:digit:]]+\.[[:digit:]]*)|(\.[[:digit:]]+))([eE][+-]?[[:digit:]]+)?
Wie man sieht, werden REs schnell unübersichtlich.
Das Chaos wird in Verbindung mit sed und bash perfekt, da sich noch viele
lustige '\' und '/' hinzugesellen werden. Dazu aber später.
Mit REs lassen sich nicht alle Zeichenketten beschreiben. Es ist zum Beispiel unmöglich ein System von balancierten Klammern zu beschreiben, auch ist die Menge {wcw | w ist ein String bestehend aus 'a's und 'b's} als RE nicht auszudrücken. Mehr zu REs kann man im 'Drachenbuch', Compilers - Principles, Techniques and Tools von Aho, Sethi und Ullman nachlesen.
sed verwendet Basic Regular Expressions, eine Art Untermenge der oben vorgestellten Erweiterten Regulären Ausdrücke. Einige Unterschiede sind:
Die Quantifikatoren "|", "+" und "?" sind normale Zeichen,
und es gibt keine äquivalenten Operatoren dafür.
GNU-sed kennt diese Operatoren, wenn sie durch einen vorangestellten Backslash "escaped" werden
Die geschwungenen Klammern sind normale Zeichen, und müssen mit Backslashes "escaped" werden,
werden also als "\{" und "\}" geschrieben.
Das selbe gilt für runde Klammern; die Zeichen, die durch "\(" und "\)"
eingeschlossen werden, können später mit "\1" usw. dereferenziert werden
"^" ist ein normales Zeichen, wenn es nicht am Beginn einer Zeile oder eines Klammerausdrucks steht
"$" ist ein normales Zeichen, wenn es nicht am Ende einer Zeile oder eines Klammerausdrucks steht
"*" ist ein normales Zeichen am Beginn einer Zeile oder eines Klammerausdrucks