Liebe Besucher, ein aktueller Hinweis in eigener Sache:
Es ist beabsichtigt, diese Seiten und die Domain im Januar/Februar 2004 auf
einen anderen Server umzuziehen. Es ist leider nicht auszuschließen,
daß es während des Umzugs zu technischen Problemen mit diesen
Seiten kommen wird. Insbesondere im eMail-Bereich wird es vermutlich Probleme
geben. Wenn Sie fragen haben oder mich sonstwie erreichen wollen empfehle
ich an rebel@snafu.de zu posten.
Nachdem der Umzug abgeschlossen ist, wird es allerdings auch inhaltliche Änderungen
während des ersten Halbjahrs 2004 geben. Keine Angst. Es werden keine
Inhalte verlorengehen, aber die Struktur der Seiten wird komplett geändert.
Diese Seite hat eben eine andere Entwicklung genommen seit 2000, als das Projekt
gestartet wurde ;-) Ich werde mich bemühen, daß bei ihnen vorhandene
alte Bookmarks wenigstens zu einem Verweis auf die Neustruktur führen,
und die gesuchten Inhalte für sie trotzdem leicht und schnell auffindbar
sein werden.
Die eigentlich zu dieser Seite gehörenden Domains ag-intra.com, ag-intra.org
und ag-intra.de werden von mir geschlossen bzw. gelöscht und unregistriert.
Beschreibung - Regular Expressions
- Reguläre Ausdrücke
Copyright 2001 by Frank
Gehde
Reguläre Ausdrücke,
oder eben auch Regular Expressions trifft man immer wieder an bei der Arbeit
mit Linux. In vielen Fällen kann man sich einfach mit gequoteten Strings
behelfen, oder braucht nur einfache Treffer. Will man aber zum Beispiel einen
Treffer erzielen, wenn genau zwei bestimmte Strings in einer Textzeile vorkommen,
muß man sich bereits mit den Operatoren der Regular Expressions auseinandersetzen.
Für den Einsteiger sieht das erst einmal ziemlich chaotisch und kompliziert
aus. Wenn man das Konzept jedoch erst einmal verstanden hat, dann ist es
gar nicht so schwer.
Kurzreferenz nach Operatoren
Op. |
Name |
Bsp. |
Match |
no Match |
f*2 |
Match-Self |
`blafasel` |
blafasel |
blufasel |
. |
Match-Any-Character |
`bl.` |
bla, blu |
bal, bul |
\ |
Backslash |
`inter\.net` |
inter.net |
inter-net |
* |
Match-Zero-Or-More |
`bla*` |
bl, blaaa |
ba, bar |
+ |
Match-One-Or-More |
`bla+` |
bla, blaa |
bl, ba |
? |
Match-Zero-Or-One |
`ball?` |
bal, ball |
ba, bull |
{ } |
Interval |
`z{3}` |
zzz |
z, zzzz |
{9, }*1 |
Interval |
`z{2,}` |
zz, zzzz |
z |
{9,9}*1 |
Interval |
`z{2,3}` |
zz, zzz |
z. zzzz |
[ ] |
Matching-List |
`[au]nd` |
and, und |
ind, mnd |
[^ ] |
Non-Matching-List |
`[^au]nd` |
ind, mnd |
and, und |
[[: :]] |
Character Class |
`[[:digit:]]` |
1, 2, 3 |
a, b, c |
[ - ] |
Range |
`[a-e]` |
a, b, d, e |
f, g, t |
( ) |
Grouping |
`(br)+` |
br, brbrbr |
r, rrr, b |
| |
Alternation |
`and|und` |
and, und |
ind, mnd |
\9*1 |
Back-Reference |
`(z)\1` |
zz |
z, a, r |
^ |
Beginning-Of-Line |
`^time` |
time out |
last time |
$ |
End-Of-Line |
`time$` |
last time |
time out |
|
|
|
|
|
*1 - Die 9 steht stellvertretend
für eine beliebige Ziffer
*2 - Das f steht stellvertretend
für ein beliebiges ordinäres Zeichen
Sprachgebrauch dieser Anleitung
In der englischen Literatur und in den Manpages zu den betreffenden Programmen
und Kommandos wird man in Zusammenhang mit Regular Expressions immer wieder
auf die Begriffe character, operator, match, ordinary, special, und pattern
treffen. Für character werden wir hier Zeichen verwenden. Die anderen
Begriffe verwende ich hier in deutscher Schreibweise (operator, ordinär,
spezial/speziell, Pattern). Eine Sonderstellung hat match. In deutscher Übersetzung
müßte je nach Zusammenhang immer wieder ein anderes Wort für
match verwendet werden, was aber der Philosophie von Regex entgegensteht.
Daher wird an den entsprechenden Stellen das englische Wort Match verwendet
oder in (ekelhafter) eingedeutscher Form (gematcht). Dieses Wort bezeichnet
je nach Zusammenhang Treffer, Zutreffend oder auch Beschreibend.
Da es immer wieder um Zeichenketten geht, kommt dieser Begriff auch häufig
vor. Ich werde jedoch den englischen Begriff String verwenden. Dies sollte
keine Probleme aufwerfen.
Ansonsten sind in den Beispielen zur optischen Unterscheidung möglichst
alle Kommandos in dunkelblau,
alle regulären Ausdrücke in dunkelgrün
und alle System- oder Programmausgaben in schwarz dargestellt.
Anwendung
Fälle, in denen man sich mit der Bildung von Regular Expressions auseinandersetzen
muß, sind die Kommandos grep, egrep, die Programme emacs und logsurfer
und die Programmiersprachen C, Perl und Python (Java inzwischen auch). Diese
Aufzählung ist nicht abschließend. In allen Fällen geht es
darum ein Muster oder auch Pattern aus Operatoren zu erstellen, welches dann
mit einem Text verglichen wird. Kommt der Inhalt, der durch die Operatoren
beschrieben wird in dem Text vor, so gibt es einen Treffer(Match). Der Vergleich
mit dem regulären Ausdruck wird wahr, was dann entsprechende Reaktionen
des Kommandos oder Programms zur Folge haben kann. Je nach Anwendung (zB
mit egrep oder logsurfer) sollte der reguläre Ausdruck in Hochkommata
eingeschlossen sein (´Ausdruck´). Welches der drei Hochkommata
auf der Tastatur das sein muß, müssen Sie selbst herausfinden
;-) Bei AWK müßen die regulären Ausdrücke dagegn zwischen
Slashes (/Ausdruck/) stehen.
Beispiel: |
Um festzustellen, ob die
Datei inetd.confim Verzeichnis /etc existiert, könnte
man, wenn man in diesem Verzeichnis steht, das Kommando
>ls | grep ´inetd´
eingeben. Die Ausgabe lautet z.B.
inetd.conf
inetd.conf.old
Das schränkt das lange Listing des Verzeichnisses
ganz praktisch ein. Die Ausgabe von ls wird durch die Pipe (|)
an das Kommando grep weitergegeben. Dies vergleicht jede Zeile der
Ausgabe von ls mit dem Pattern (inetd) und druckt nur die
Zeilen, in denen dieses Pattern vorkommt.
Natürlich könnte man auch nur ls inedtd* eingeben.grep
kann mit einer Regular Expression aber auch andere Ausgaben des ls
Befehls auswerten. Mit
>ls -lFa | grep ´.......rw.´
können sie sich zum Beispiel anzeigen lassen, welche
Dateien im etc-Verzeichnis worldwritable sind, welche also durch jeden Nutzer
geändert werden können. Die Parameter lFa bei ls
bewirken eine detailliertere Ausgabe, die dann von grep ausgewertet
wird. Wie der Ausdruck aufgebaut ist, erklärt sich unten.
|
Philosophie der Regular Expressions
Bei den ersten Berührungen mit Regular Expressions bekommt man den Eindruck,
als würden einfach nur zwei Strings miteinander verglichen werden. Das
ist aber nicht ganz so, was dann später in der Anwendung zu Mißverständinissen
und mithin Fehlern führen kann. Das, was der Regex-Engine (also dem
auswertenden 'Modul') eingegeben wird, ist ein String. Das, womit verglichen
wird, also der reguläre Ausdruck, ist eine Sammlung quasi-mathematischer
Operatoren, die einen String beschreiben.
Es gibt zwei Arten von Zeichen. Die ordinären Zeichen und die speziellen
Zeichen. Die ordinären Zeichen matchen sich in der Regel selbst. Die
speziellen Zeichen beschreiben in der Regel allgemeinere Umstände für
Matches. Im Zusammenhang mit speziellen Zeichen kann es auch vorkommen, daß
ordinäre Zeichen eine Sonderbedeutung erlangen.
Beispiel: |
-Ein regulärer Ausdruck,
der nur aus ordinären Zeichen besteht wäre zum Beispiel:
´foo´
Dies würde auf alle Strings matchen, die die Zeichen
fooenthalten.
-Ein regulärer Ausdruck, der nur aus speziellen Zeichen besteht wäre
zum Beispiel:
´.*´
Dies würde auf jeden String matchen.
|
Syntax Bits, Posix-, Gnu-Operatoren etc.
Dies ist eine allgemeinere Erklärung zu Regulären Ausdrücken.
Programmierer können die Auswertung der regulären Ausdrücke
z.B. noch durch Syntax Bits steuern. Dies wird hier nicht weiter beschrieben.
Sollte mal etwas gar nicht funktionieren, so könnte das an der konkreten
Implementierung des jeweiligen Programms liegen, welches mit den Syntax Bits
etwas rumgespielt hat. Außerdem wird noch unterschieden zwischen den
Posix-Operatoren, den GNU-Operatoren und den GNU-Emacs-Operatoren (die sich
in dieser Reihenfolge ergänzen) und ggf. weiteren Spezial-Operatoren.
Diese Anleitung beschränkt sich im wesentlichen auf die Posix- und die
GNU-Operatoren, die eigentlich in den meisten Anwendungen im Linux-Umfeld
funktionieren müßten.
Das Backslash Zeichen \
Das Backslash Zeichen nimmt gewissermaßen eine Sonderstellung ein.
Es dient als Escape-Zeichen um speziellen Zeichen Ihre Sonderstellung zu
nehmen und sie als ordinäre Zeichen zu behandeln. In Listen erhält
es keine Sonderstellung, sondern steht für sich selbst (ist also selbst
ordinär). Übrigens: Fast alle speziellen Zeichen verlieren
in Listen ihre Sonderstellung und werden als ordinär betrachtet.
Der Backslash kann außerdem gemäß der GNU-Operatoren Spezifikation
bestimmte spezielle Zeichen einleiten.
Beispiel: |
-Außerhalb einer Liste
als Escape-Zeichen. Zum Beispiel:
´www\.ag-intra\.net´
Dies würde nur auf den String "www.ag-intra.net"
matchen, aber nicht zB. auf den String "www/ag-intra/net". Der Punkt, der
eigentlich ein spezielles Zeichen mit Sonderbedeutung ist, wird durch den
Backslash als ordinäres Zeichen interpretiert.
-In einer Liste steht der Backslash ordinär für
sich selbst. Zum Beispiel:
´[\b]rei´
matcht zB. den String "brei", "breit" oder "\rei" aber
nicht den String "schrei". Siehe auch Listen-Operatoren
unten.
-Außerhalb einer Liste können je nach folgendem
Zeichen spezielle Zeichen in Form von GNU-Operatoren eingeleitet werde. Die
Zeichen sind b, B, <, >, w, W und ` (siehe auch GNU-Operatoren). Zum Beispiel:
´\bbrei\b´
Dies würde auf eine Zeile matchen, in der der String
"brei" als einzelnes Wort vorkommt, nicht jedoch auf eine Zeile, in der zB.
der String "breit" vorkommt.
|
In anderen Fällen, zB. bei "\n" außerhalb
von Listen, wird der Backslash einfach ignoriert, da er unsinnig ist ("\n"
würde also im Beispiel das gleiche wie "n" sein).
Die Posix Operatoren
Gehen wir nun ans Eingemachte und betrachten die einzelnen Standard-Operatoren
nach dem Posix-Standard:
Die Selbst-Matchenden
Operatoren
Alle ordinären Zeichen sind sich selbst matchende Operatoren. Der reguläre
Ausdruck wird wahr, wenn das ordinäre Zeichen im untersuchten String
vorkommt.
Beispiel: |
Der reguläre Ausdruck
mit einem ordinären Zeichen:
´f´
würde bei folgenden Strings matchen:
f
Sauerstoffflasche
|
Der Jedes-Zeichen-Matchende
Operator .
Dieser Operator trifft auf jedes einzelne druckbare oder nicht druckbare Zeichen
zu, außer unter Umständen auf ein Newline-Zeichen (Neue Zeile)
oder auf Null-Zeichen, also leere Strings. Das Punktzeichen (.) repräsentiert
diesen Operator.
Beispiel: |
Der reguläre Ausdruck
mit Punkt-Operator:
´.´
würde bei folgenden Strings matchen:
fa
b
c
abc
und so fort
|
Operatorenverkettung
In der Regel wird der reguläre Ausdruck durch Verkettung von Operatoren
gebildet. Dies erfolgt ohne Leerzeichen (je nach Programm in dem die regulären
Ausdrücke gebraucht werden) einfach durch Hintereinanderschreiben von
Operatoren.
Beispiel: |
-Der reguläre Ausdruck,
der nur aus ordinären Zeichen (Selbst-Matchenden-Operatoren) besteht
wäre zum Beispiel:
´bla´
Dies würde auf alle Strings matchen, die irgendwo
den String "bla"enthalten.
-Ein regulärer Ausdruck, der aus ordinären Zeichen (Selbst-Matchenden-Operatoren)
und speziellen Zeichen (hier der Jedes-Zeichen-Matchende Operator) besteht
wäre zum Beispiel:
´b.a´
Dies würde auf die Strings "bla", "bba", "bra"
aber nicht auf die Strings "faa", "zaa" zutreffen.
-Um genau den String "b.a" zu treffen (außerhalb von Listen),
wäre das Quoten mit dem Backslash erforderlich. Ein regulärer Ausdruck,
der also genau diesen String treffen soll, und nicht etwa den String "bla",
würde so aussehen:
´b\.a´
|
Der Matche-Keinen-Oder-Mehr
Operator *
Dieser Operator gehört zu den sogenannten Wiederholungsoperatoren
(wie auch die beiden folgenden Operatoren). Dieser Operator trifft dann zu,
wenn das kleinstmögliche vorhergehende Zeichen keinmal, einmal oder
beliebig oft hintereinander vorkommt. Kleinstmöglich heißt in
diesem Fall, daß in der Regel genau nur das eine Zeichen, daß
vor dem Stern steht betroffen ist. Um eine längere Kette mit dem Operator
zu verbinden müßten die Zeichen vor dem Stern gruppiert werden
(siehe unten). Steht kein Zeichen
vor dem Operator, wird er als ordinäres Zeichen interpretiert. .
Beispiel: |
-Ein regulärer Ausdruck
mit dem Stern-Operator wäre zum Beispiel:
´bl*´
Dies würde auf "b", "bl", "ba", "bla", "blll" matchen.
-Wer dies unsinnig empfindet, wartet nur auf einen sinnvollen praktischen
Anwendungsfall.Wenn Sie zum Beispiel ein Logfile untersuchen, und nur an Zeilen
interessiert sind, in denen im vorderen Teil der String "bla" vorkommt, und
etwas weiter hinten der String "fasel". Außerdem wissen Sie, daß
zwischen den Strings andere Zeichen vorkommen, die aber beliebig und in beliebiger
Anzahl erscheinen. Ein regulärer Ausdruck der Ihnen genau diese Zeilen
herausfiltert sieht zum Beispiel so aus:
´bla.*fasel´
Dies würde auf die Strings "blafasel", "bla/f/g/h/fasel",
"bla-fasel" matchen, aber nicht auf die Strings "bla/und/sowieso" oder "sowiesofasel".
Hier wurden zwei spezielle Zeichen in Beziehung gesetzt. .* bedeutet,-
jedes beliebige Zeichen-, -beliebig oft oder sogar keinmal-.
|
Der Matche-Einen-Oder-Mehr
Operator +
Dieser Operator gehört auch zu den sogenannten Wiederholungsoperatoren.
Es kann nötig sein, ihn als \+ zu notieren. Er verhält sich ähnlich
wie der Stern-Operator, erfordert aber mindestens einmal das Auftreten des
vorhergehenden Zeichens.
Beispiel: |
-Ein regulärer Ausdruck,
der mit dem Plus-Operator arbeitet wäre zum Beispiel:
´bl+´
Dies würde auf "bl", "bla", "blll" matchen, nicht
aber auf "b" oder "ba".
-Wollte man zum Beispiel einen Treffer bei banabana erzielen, aber nicht
bei banana (also es muß ein n vor dem b vorkommen, und beide dürfen
nicht direkt hintereinander stehen) könnte man schreiben:
´n.+b´
Dies würde auf den String "banabana" matchen, nicht
aber auf "banana"
-Wer ein Chat-Logfile untersucht, möchte vielleicht alle Zeilen, in
denen das Wort "ganz" vorkommt finden. Nun ist es bei Chattern oft so, daß
sie zum Beispiel schreiben "ich hab dich ggaaanz doll lieb". Um unabhängig
von der Zahl der Wiederholungen diese Zeilen zu finden, könnte man den
regulären Ausdruck
´g+a+n+z+´
verwenden. Er findet sowohl "ganz" als auch jede Kombination
von "ggaaannzz".
|
Der Matche-Keinen-Oder-Einen
Operator ?
Dieser Operator gehört auch zu den sogenannten Wiederholungsoperatoren.
Es kann nötig sein, ihn als \? zu notieren. Er funktioniert ähnlich
wie der Stern-Operator, erlaubt das vorhergehende Zeichen aber nur keinmal
oder genau einmal.
Beispiel: |
-Ein regulärer Ausdruck,
der mit dem Fragezeichen-Operator arbeitet wäre zum Beispiel:
´bl?a´
Dies würde auf "bla" und "ba" matchen, nicht aber
auf "blla" oder "blu".
-Sucht man zum Beispiel nach einem regulären Ausdruck, der berücksichtigt,
daß das Wort Sauerstoffflasche ab und an falsch geschrieben wird, so
könnte man das so formulieren:
´Sauerstofff?lasche´
Dies würde auf die Strings "Sauerstofflasche"
und "Sauerstoffflasche" matchen aber auf keinen anderen.
|
Die Intervall-Operatoren
{}
Es kann nötig sein, diese als \{ und \} zu notieren.Hiermit kann
die genaue Anzahl von Malen, oder ein Anzahlbereich angegeben werden, die
ein Zeichen hintereinander auftreten muß, um einen Match zu erzielen.
Dabei gibt es drei zulässige Schreibweisen:
{Anzahl} |
Die genaue Anzahl, die ein Zeichen auftreten muß. |
{min,} |
Das Zeichen muß mindestens min-Mal oder
mehr auftreten. |
{min, max} |
Das Zeichen muß mindestens min-Mal auftreten,
darf aber höchstens max-Mal vorkommen. |
Dabei ist es unzulässig einen höheren min-Wert mit
einem niedrigeren max-Wert anzugeben.
Beispiele |
reg. Ausdruck |
matcht |
matcht nicht |
|
´ga{3}nz´ |
gaaanz |
ganz
gaanz
gaaaaaaaaanz |
|
´ga{2,}nz´ |
gaanz
gaaaaaaanz |
ganz |
|
´ga{2,5}nz´ |
gaanz
gaaaaanz |
ganz
gaaaaaaaaanz |
Der Alternativ Operator
|
(Achten sie zum Beispiel beim Einsatz von grep oder egrep auf die Hochkommata,
da der Operator sonst mit einer Pipe verwechselt werden könnte). Es kann
nötig sein, den Operator als \| zu notieren.
Dieser Operator läßt eine oder mehr Alternativen zu, um zu matchen.
Dabei betrachtet er immer den größtmöglichen ihn umgebenden
String. Um die Länge der Alternativ-Strings zu begrenzen ist es notwendig
zu gruppieren.
Beispiel: |
-Ein regulärer Ausdruck,
mit zwei Alternativ Strings wäre zum Beispiel:
´bla|fasel´
Dies würde auf die Strings "bla" oder fasel" matchen.
-Soll das obige Beispiel auf nur einen Teil begrenzt werden,so könnte
so gruppiert werden:
´bl(a|f)asel´
Dies würde auf "blaasel" und "blfasel" matchen,
aber nicht auf "blafasel".
|
Die Listen Operatoren []
und [^]
Die Listen-Operatoren enthalten ein oder mehrere Listenelemente und stehen
meist für genau ein Zeichen. Ein Listenelement kann eine Alternativliste,
ein Zeichenklassenausdruck oder ein Bereichsausdruck sein. Für die erstgenannten
Elemente, die Alternativlisten hier ein Beispiel:
Beispiel: |
-Ein regulärer Ausdruck,
mit einer Alternativliste an Elementen:
´[kflr]ind´
Dies würde auf die Strings "kind", "find", "blind"
und "rind" matchen, aber nicht auf "sind" oder "wind".
|
Eine Nicht-Matchende Liste wird ähnlich erstellt. Nur
das der öffnenden Klammer ein Höherzeichen (^) nachgestellt wird:
Beispiel: |
-Ein regulärer Ausdruck,
als Nicht-Matchende Liste:
´[^kflr]ind´
Dies würde zB. auf die Strings "sind" oder "wind"
matchen, aber nicht auf "kind", "find", "blind" und "rind".
|
In derartigen Listen verlieren praktisch alle speziellen Zeichen
ihre besondere Bedeutung und werden ordinär. Dies betrifft auch und
insbesondere den Punkt-Operator. Spezielle Bedeutung in Listen haben noch
folgende Zeichen: "[:", ":]", "-", "\" und "]". Die Bedeutung
wurde oben schon erwähnt. Kommen wir damit nämlich zu der nächsten
Art von Listenelementen, den Zeichenklassenausdrücken.
Dies sind praktisch vordefinierte Konstanten, die immer in geschlossenen Klammern
mit dem Doppelpunkt stehen [:ausdruck:]. Es gibt folgende Zeichenklassenausdrücke:
Klasse |
Bedeutung |
alnum |
An dieser Stelle einen Buchstaben oder eine Ziffer |
alpha |
An dieser Stelle einen Buchstaben |
blank |
An dieser Stelle ein Leereichen oder Tab |
cntrl |
An dieser Stelle ein Kontrollzeichen (ASCII 177 oder
< 040) |
digit |
An dieser Stelle eine Ziffer |
graph |
An dieser Stelle ein druckbares Zeichen (Tilde, ASCII
040-176) |
lower |
An dieser Stelle ein kleingeschriebener Buchstabe |
print |
An dieser Stelle ein druckbares Zeichen (Leerzeichen,
Tilde, ASCII 040-176) |
punct |
An dieser Stelle kein alphanumerisches Zeichen oder
Kontrollzeichen |
space |
An dieser Stelle ein Leerzeichen, Wagenrücklauf,
Neue Zeile oder Seitenvorschub |
upper |
An dieser Stelle ein großgeschriebener Buchstabe |
xdigit |
An dieser Stelle eine hexadezimale Ziffer (0-9, a-f,
A-F) |
Bevor wir zu einem Beispiel kommen, sehen wir uns noch die
dritte Art von Listenelement an, die Bereichsausdrücke mit dem Bereichsoperator
"-". Ein Bereich wird durch Start- Und Endzeichen angegeben. Bereichsausdrücke
sind zB. [a-z] und [1-5]. Im ersten Fall führt es zu einem Match, wenn
das untersuchte Zeichen ein kleiner Buchstabe ist, und im zweiten Fall, wenn
es sich um eine der Ziffern von 1 bis 5 handelt. Es ist nicht zulässig
einen Bereich rückwärts anzugeben ([z-a]). Im folgenden Beispiel
wird versucht bei allen Zeilen einen Treffer zu erzielen, die eine IP-Adresse
beinhalten (auf Gültigkeit kann in dem Beispiel nicht ganz geachtet
werden, weil die Formulierung des regulären Ausdrucks auch Werte von
299 zulässt).
Beispiel: |
-Es folgt ein regulärer
Ausdruck, der unter anderem aus mehreren Listen besteht und auf IP-Adressen
matcht. Der Ausdruck ist in der Mitte einmal gebrochen, wegen seiner Länge.
Stellen Sie ihn sich einfach als eine Zeile vor:
´[1-2]?[0-9]?[[:digit:]]\.[12]?[0-9]?[[:digit:]]\.
[1-2]?[[:digit:]]?[[:digit:]]\.[12]?[0-9]?[[:digit:]]\.´
Sie sehen verschiedene Listen, den Fragezeichenoperator
und den Punkt-Operator mit Backslash. Die erste Liste, die man sieht beschreibt
einen Bereich. Und zwar für alle Zahlen von 1 bis 2. Das folgende Fragezeichen
sagt aus, daß diese Zahl dann entweder ein- oder keinmal vorkommen
muß. Da in IP's Nummern zwischen 0 und 255 zulässig sind, muß
bei weniger großen Zahlen als 255 damit gerechnet werden, daß
sie zwei- oder einstellig sind. Daher hier das Fragezeichen, daß auch
das keinmalige Vorkommen erlaubt. Das gleiche gilt für die zweite Liste.
Diese gibt einen Bereich von 0-9 an, da zumm Beispiel bei dem IP-Wert 199
auch eine 9 möglich ist. Leider wird dadurch nicht sichergestellt, daß
ein IP-Wert von 260 unmöglich ist, und dann nicht matcht. Der nächsten
Liste ist kein Fragezeichen nachgestellt, da eine Ziffer pro IP-Wert immer
vorkommen muß. Dies kann dann ebenfalls eine Ziffer von 0-9 sein. In
diesem Fall wurde dieser Bereich allerdings mit einem Zeichenklassenausdruck
angegeben. Man muß beachten, daß Zeichenklassenausdrücke
immer in [:ausdruck:] eingeschlossen werden müßen. Diese bilden
dann das Listenelement und stehen wieder in eckigen Klammern. Daher resultieren
die verschachtelten Klammern. Nun kommt ein Backslash mit einem Punkt, was
bedeutet, daß ich hier nicht das spezielle Zeichen Punkt-Operator verwende,
sondern auf das ordinäre Zeichen Punkt matchen möchte. Als nächstes
folgt wieder eine Liste. Diese entspricht genau der allerersten Liste, ist
diesmal jedoch als Aufzählung formuliert. Das ganze setzt sich bis zum
Ende wie beschrieben fort, wobei die Art der Formulierung variiert wird,
um Möglichkeiten der Formulierung zu zeigen. Wenn Sie eine Datei mit
IP-Adressen erstellen, deren einzelne Werte unterschiedlich ein- bis dreistellig
sind, und dann einen egrep über diese Datei laufen lassen, werden Sie
sehen, daß es funktioniert.
Mit den Intervall-Operatoren kombiniert könnte man den obigen Ausdruck
auch so formulieren:
´[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}´
Man würde jedoch mit dieser Formulierung auch bei
den hunderter Stellen alle Werte zulassen und 999 wäre dann ein Match.
|
Die Gruppen Operatoren
()
Es kann nötig sein, diese als \( und \( zu notieren. Beim Stern-Operator
und beim Alternativ-Operator wurde die Gruppierung ja bereits angesprochen.
Genau wie in der Mathematik mit den Klammern ein geschlossener Ausdruck gebildet
wird, geschieht das auch hier. Man kann also hiermit die Zahl der Zeichen
verändern, die auf einen Stern-, Plus-Operator oder einen Alternativ-Operator
wirken. Außerdem kann man auf die Indexe derartiger Gruppen zurückgreifen.
Beispiel: |
-Ein regulärer Ausdruck,
der viel blabla matchen würde:
´(bla)+´
Dies würde auf alle Strings matchen, die mindestens
einmal oder mehrmals den String "bla" enthalten. zB. "bla", "blablabla" etc..
-Ein regulärer Ausdruck, mit zwei Alternativen Screibweisen eines Strings
wäre zum Beispiel:
´bl(a|u)fasel´
Dies würde auf "blafasel" und "blufasel" matchen,
aber nicht auf "blofasel".
|
Der Back-Referenz
Operator\ziffer
Diesen habe ich jetzt nicht direkt übersetzt. Dieser Operator referenziert
eine Gruppe, die sich vor dem Back-Referenz Operator befindet. Die Gruppen
werden durchnummeriert und entsprechend wird die Zahl der Referenz geschrieben.
Beispiel: |
-Ein regulärer Ausdruck,
der einen einfachen Back-Referenz Operator enthält wäre zum Beispiel:
´(bla)\1´
Dies würde auf "blabla" matchen. Die erste Gruppe
matcht auf "bla" und der Back-Referenz Operator matcht auf das, auf was auch
die referenzierte Gruppe (Nummer 1) gematcht hat..
-Ein regulärer Ausdruck, der interessant ist:
´(.*)\1´
Dies würde auf jeden String matchen, der aus genau
zwei identischen Hälften zusammengesetzt ist, wie zB "hulahula".
-Mit mehreren Gruppen sieht das so aus:
´(h.h.).*(toll).*\1.*\2´
Dies würde zB. auf den String "hihi, das ist toll!
hihihi nee doch nich toll" matchen, aber nicht auf den String "haha, das
ist toll! hihihi nee doch nich toll" . Der Ausdruck (h.h.) trifft zwar einzeln
gesehen auf "hihi" und "haha" zu, aber der Back-Referenz-Operator verwendet
für den Match nicht den regulären Ausdruck aus der ersten Gruppe,
sondern den konkreten String, der bei der ersten Gruppe einen Match erzeugt
hat.
-Der Back-Referenz Operator läßt sich auch mit Intervallen (oder
anderen Wiederholungsoperatoren) kombinieren:
´(hu(ha))\2{3}´
Dies würde dann genau auf den String "huhahahaha"
matchen.
|
In manchem Programmen kann auch mit Variablen auf die Gruppen-Referenzen
zurückgegriffen werden (zB. logsurfer).
Der Matche-Am-Anfang-Der-Zeile
Operator ^
Dieser Operator gehört zu den Ankeroperatoren, die den Match auf den
Anfang oder Ende einer Zeile beschränken. Hier wird konkret auf den
Anfang geprüft. Der Operator wird nur dann als spezielles Zeichen erkannt,
wenn er am Anfang des gesamten regulären Ausdrucks steht, oder er genau
hinter einem Gruppe-Öffnen-Operator oder Alternativ-Operator steht.
In allen anderen Fällen kann davon ausgegangen werden, daß das
Zeichen als ordinäres Zeichen betrachtet wird (außer in Listen,
die es negieren kann. Aber in Listen ist eh alles anders ;-):
Beispiel: |
-Ein regulärer Ausdruck,
der bestimmt, daß die Folgeoperatoren nur am Anfang einer Zeile matchen:
´^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}´
Dieser Ausdruck würde bewirken, daß jede
Zeile matcht, die mit einer IP-Adresse beginnt..
-Ein regulärer Ausdruck, der dann matcht, wenn eine Zeile entweder mit
"bla" oder "fasel" beginnt:
´bla|^fasel´
Dies würde auf jeden String oder jede Zeile matchen,
die entweder mit bla oder mit fasel beginnt.
|
Der Matche-Am-Ende-Der-Zeile
Operator $
Der Ankeroperator, der das Pattern des regulären Ausdrucks am Ende des
Strings bzw. der Zeile verankert. Der Operator wird nur dann als spezielles
Zeichen erkannt, wenn er am Ende des gesamten regulären Ausdrucks steht,
oder er genau vor einem Gruppe-Schließen-Operator oder Alternativ-Operator
steht. In allen anderen Fällen kann davon ausgegangen werden, daß
das Zeichen als ordinäres Zeichen betrachtet wird.
Beispiel: |
-Ein regulärer Ausdruck,
der bestimmt, daß die vorigen Operatoren nur am Ende einer Zeile matchen:
´TCP_MISS$´
Dieser Ausdruck würde bewirken, daß jede
Zeile matcht, die mit dem String "TCP_MISS" endet.
-Ein regulärer Ausdruck mit Alternativ Operator:
´bla$|fasel´
Dies würde auf jeden String oder jede Zeile matchen,
die entweder mit "bla" endet, oder in der "fasel" vorkommt.
-Ein weiterer regulärer Ausdruck mit Alternativ Operator:
´bla|fasel$´
Dies würde auf jeden String oder jede Zeile matchen,
die entweder mit "bla" , oder "fasel" endet.
-Ein weiterer regulärer Ausdruck mit Alternativ Operator:
´bla$|fasel$´
Das ist dasselbe wie vorher.
|
Die GNU-Operatoren
Diese Operatoren werden von GNU definiert und sind nicht mehr Posix-konform.
Je nach Anwendung können diese eingesetzt werden.
Achtung: Wegen einiger Mißverständlichkeiten
in der Anwendung der GNU-Operatoren ist dieser Abschnitt noch nicht fertig
und zeigt nur die Anwendung des ersten GNU-Operators. Falls jemand
wirklich versteht, worin die Unterschiede von \b \< \> liegen
... oder die Unterschiede zwischen \B \w \W, dann kann er mir gerne mailen.
Ich versteh den Unterschied nämlich jeweils nicht. Die RegEx
Library Dokumentation kann hierzu eingesehen werden.
Der Matche-Am-Wort-Rand
Operator \b
Hier muß der der reguläre Ausdruck entweder am Wortanfang oder
an einem Wortende stehen, damit ein Match stattfindet:
Beispiel: |
-Ein regulärer Ausdruck,
mit dem Operator vorne:
´\bbla´
Dies würde auf alle Strings matchen, die mit bla
beginnen, wie "bla" oder "blabber".
-Ein regulärer Ausdruck, mit dem Operator hinten:
´fasel\b´
Dies würde auf jeden String matchen, der mit fasel
aufhört, wie zB "fasel" oder "blafasel".
-Ein regulärer Ausdruck, mit dem Operator hinten und vorn:
´\bbla\b´
Dies würde nur und genau auf das einzeln stehende
Wort "bla" matchen.
|
Annex
Quelle: Regex
Dokumentation von Kathryn A. Hargreaves und Karl Berry (Beschreibung der
Posix-, Gnu- und BSD-kompatiblen Regex Library).
Dank an Kai wegen der Erleuchtung bei den GNU-Operatoren.
Die vorliegende Erklärung steht genauso unter der GNU GPL wie die Regex Doku.
Linkergänzung 27.08.2001: http://www.heise.de/ix/artikel/2001/09/139/
IX-Artikel
zurück
zur Linux Übersicht |