ToDo: Kontrolle
ToDo: Unpdate Links

FAQ - Hamster und Reguläre Ausdrücke (RegEx)

Allgemein

Die im Hamster verwendeten „regular expression“-Funktionen nutzen eine Win32-Umsetzung von „Perl Compatible Regular Expression (PCRE)“, geschrieben von Philip Hazel (<ph10@cam.ac.uk>), Copyright (c) 1997-2000 University of Cambridge (Näheres unter ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/).

In den Dateien „Scores.hst“, „MailFilt.hst“, in einigen Einstellungen der grafischen Oberfläche bzw. in den dazugehörenden INI-Einstellungen und in einigen Hamsterskript-Funktionen werden „Regular Expressions“ („Reguläre Ausdrücke“, kurz auch RegEx/RegExp oder RE) verwendet. Hierzu eine kurze Erläuterung ohne Anspruch auf Vollständigkeit.

Umfassende Informationen sind auf http://perldoc.perl.org/perlre.html zu finden (dies ist die Perl-Dokumentation für Reguläre Ausdrücke) oder sind z. B. im Buch „Mastering Regular Expressions“ nachzulesen („das Eulen-Buch“ – Verlag O‘Reilly Media; ISBN Buch 978-0-596-52812-6, ISBN E-Book 978-0-596-55899-4), auf deutsch erschienen als „Reguläre Ausdrücke“ (ISBN Buch 978-3-89721-720-1, ISBN E-Book 978-3-89721-790-4). Eine kurze deutschsprachige Einführung ist bei SelfHTML unter http://wiki.selfhtml.org/wiki/Doku:Perl/Reguläre_Ausdrücke zu finden oder auch in der Wikipedia unter http://de.wikipedia.org/wiki/Regulärer_Ausdruck.

Zu beachten ist, dass im Hamster die Markierung Regulärer Ausdrücke anders erfolgt als in den genannten, auf Perl bezogenen Dokumentationen, siehe unten zur Definition Regulärer Ausdrücke.

Anmerkungen zu den hier verwendeten Begriffen

Wie oft in der Informationstechnik werden auch hier aus dem Englischen stammende Fachbegriffe oder davon abgeleitete Ausdrücke verwendet.
Englischer Ausdruck Deutsche Bedeutung
caseless/caseinsensitive Groß- und Kleinschreibung wird ignoriert
casesensitive Groß- und Kleinschreibung wird beachtet
carriage return Wagenrücklauf; erinnert an Schreibmaschine (Bedeutung: siehe newline)
character Zeichen
escape character „Fluchtzeichen“, maskiert die Metabedeutung des folgenden Zeichens; davon abgeleitet „escapen“ für „Metabedeutung maskieren“
flag „Flagge“, kennzeichnet einen Schalter, der gesetzt wurde (wie Flagge hoch oder runter)
greedy „gierig“; bezieht sich auf das Verhalten von Quantifiern (siehe unten), Substantiv „greediness“ = „Gierigkeit“
to match passen; bezeichnet den Teil des untersuchten Strings, der auf den Suchstring passt; davon abgeleitet „matchen“ (Regulärer Ausdruck matcht auf Suchstring) und Substantiv „Match“ für passende Zeichenkette
newline Zeilenendezeichen; je nach Betriebssystem nur Carriage return (kurz CR) oder nur Linefeed (LF) oder Carriage Return und Linefeed (CRLF)
pattern Suchmuster, bezeichnet kompletten Matchstring
quantifier Operator, der angibt, wie oft der vorhergehende Ausdruck wiederholt werden soll/darf
string Zeichenkette
subpattern Logisch zusammengehöriger Abschnitt des Patterns (Gruppe)

Definition von Regulären Ausdrücken

Reguläre Ausdrücke sind eine Möglichkeit, Zeichenketten (Strings) mit einer Meta-Syntax zu beschreiben. Diese erlaubt es, Strings in Klassen einzuteilen und diese Klassen zu beschreiben. So kann man verschiedenartige Strings, die ein bestimmtes Element gemeinsam haben, anhand dieses Elementes klassifizieren.

Der fragliche String wird dabei von links nach rechts durchsucht und es wird der erste Match-String zurückgegeben. Standardmäßig wird dabei der längste Match zurückgegeben. Diese Verhalten wird als gierig (greedy) bezeichnet und kann bei Bedarf auch abgeschaltet werden. Ebenso ist es (im Hamster) Standard, dass die Groß- und Kleinschreibung (case) nicht beachtet wird (caseless).

Reguläre Ausdrücke werden in den Hamsterscoredateien („MailFilt.hst“ und „Scores.hst“) durch eine linke geschweifte Klammer „{“ eingeleitet und mit einer rechten geschweiften Klammer „}“ abgeschlossen. Alles dazwischen wird als Teil des Suchstrings betrachtet, die Klammern selbst gehören aber nicht zum Regulären Ausdruck. Wer Texte über Perl liest, wird dort oft „/…/“ sehen. Die Schrägstriche erfüllen hier den gleichen Zweck. In Hamsterskripten sind diese Klammern nicht notwendig, hier sind es nur bestimmte Funktionen, die Reguläre Ausdrücke erwarten, so dass bei diesen Funktionen die Regexp wie jeder andere String in Anführungszeichen eingeschlossen wird.

Achtung! In den Regulären Ausdrücken dürfen keine Kommentare aus der Syntax von „hs2“ stehen. Es dürfen aber logische Zeilenumbrüche verwendet werden, da die Zusammenfügung zu einer einzigen Zeile als allererstes erfolgt.

Beispiel („Scores.hst“):

Der Ausdruck findet wie zu erwarten alle Postings mit „mein host“ im „From“:

=-1234 from: {(?x)me_
in\shost}

Der Ausdruck

=-1234 from: {(?x)me #Zeile 1_
in\shost}

dagegen findet, auf den ersten Blick unerwartet, alle Postings mit „me“ im „From“. Die Ursache ist, dass der Hamster aus den zwei Zeilen ein

=-1234 from: {(?x)me #Zeile 1in\shost}

macht und der RegExp-Engine nur die Kette „(?x)me“ übergibt, da der Teil „#Zeile 1in\shost“ als Kommentar interpretiert wird.

Syntax

Syntax-Elemente, die außerhalb von „[ ]“ gelten

Zeichen Kurzbeschreibung
\ Allgemeiner Escape-character
^ Steht für den Beginn eines Strings oder einer Zeile
$ Steht für das Ende eines Strings oder einer Zeile
. Steht für jedes Zeichen außer newline
[ Startet Definition von Sequenzen (Zeichenklassen)
] Beendet Definition von Sequenzen (Zeichenklassen)
| Steht für logisches Oder; hiermit werden Alternativen abgetrennt
( Startet subpattern (Gruppierung)
) Beendet subpattern (Gruppierung)
? Steht für 0 oder 1 Wiederholung des vorgehenden Elementes, hebt greediness auf; Dient nach „(“ als Schalter, um Optionen einzuleiten
* Steht für 0 oder mehr Wiederholungen des vorgehenden Elementes
+ Steht für 1 oder mehr Wiederholungen des vorgehenden Elementes
{ Startet Quantifizierung (Minimum, Maximum) des vorhergehenden Elementes
} Beendet Quantifizierung (Minimum, Maximum) des vorhergehenden Elementes

Syntax-Elemente, die innerhalb von „[ ]“ gelten

Zeichen Kurzbeschreibung
\ Allgemeiner Escape-character
^ Als erstes Zeichen steht es für die Negation der beschriebenen Zeichenklasse: „[^a-z0-9]“ steht für alle nicht-alphanumerischen Zeichen
- Steht für einen Bereich „von…bis“: „[0-9]“ steht für alle Ziffern

Beispiele für die Verwendung dieser Syntax

Bevor die einzelnen Meta-Charaktere weiter erläutert werden, ein paar kurze Beispiele. Als Teststring soll hier der Satz „Regexp$ falsch angewandt erlauben einen wunderbaren Schuss in den eigenen Fuß.“ dienen (Das „$“-Zeichen steht dort absichtlich, wie gleich zu sehen ist). Alle Regexps sind als eine Zeile zu lesen.
Regexp Match Erläuterung
Reg Reg Trivialer Fall; String ohne Metabedeutung.
[reg] R Caseless; wenn kein Quantifier angegeben wurde, verhält sich der Ausdruck wie die non-greedy-Variante (siehe unten).
[reg]+ Rege Caseless; „+“ ist hier greedy und es wird nach dem längstmöglichen String gesucht, der die drei Charaktere „reg“ in beliebiger Reihenfolge und mindestens einmal enthält.
[reg]+? R Non-greedy-Variante.
[(reg)+] R „+“ hat seine Bedeutung als Quantifier nur außerhalb „[ ]“.
[^reg] X Der erste Match, der nicht „r“, „e“ oder „g“ enthält.
[a-z]+ Regexp „$“ ist kein Zeichen zwischen „a“ und „z“.
(?-i)[a-z]+ egexp Case-sensitive; diese Option erstreckt sich soweit, wie der subpattern reicht, in dem das Flag gesetzt wurde.
((?-i)[a-z]+)\$.[A-Z]+ egexp$ falsch Die Wirkung des Flags gilt nur in dem subpattern; „$“ musste markiert werden, da es eine Metabedeutung besitzt; „.“ (der Punkt) steht für genau ein beliebiges Zeichen, hier das Leerzeichen; caseless Match am Ende.
[0-9]*   Das hier ist etwas trügerisch. Wir sehen zwar keinen Matchstring, aber der Hamster erkennt dieses trotzdem als Treffer, da der „*“ auch für null Wiederholungen steht, und ein leerer String wird als Match erkannt. Hierauf ist bei der Verwendung von „*“ als Quantifier immer zu achten.

Die Bedeutung einzelner Metazeichen

Eine Bedeutung des Backslash „\“, nämlich die als Escape-Character, kennen wir schon. Wie wir in den Beispielen sahen, hilft er uns, Zeichen mit einer Metabedeutung, wie etwa das „$“-Zeichen, zu maskieren. (Wie schreibt man einen Backslash? Indem man ihn selbst maskiert: „\\“.)

Aber der Backslash unterstützt auch unsere Faulheit und hilft uns gleichzeitig, Regexps lesbarer zu schreiben. Wir sahen oben, dass man Charakterklassen mit Hilfe von „[…]“ beschreiben kann. Da dies oft vorkommt, gibt es einige Abkürzungen. Ebenso können wir mit dem Backslash nach Zeichen suchen, die wir bisher nicht finden konnten, nämlich alle nicht direkt über die Tastatur eingebbaren Zeichen.
Zeichen Kurzbeschreibung
\a Entspricht dem ASCII-Zeichen 7 (Bell)
\cx Entspricht Control-x; hier steht x für ein beliebiges Zeichen. Vergegenwärtigen wir uns, dass Control-@ für das Zeichen mit dem ASCII-Wert 0, Control-a für das Zeichen mit dem ASCII-Wert 1 steht usw.; Control-i steht dann z. B. für das Zeichen mit dem ASCII-Wert 9 = Tabulator. Die Anwendung von \cx ist etwas komplizierter als hier ausgeführt, aber dieses liest man bei Bedarf am besten in der oben aufgeführten Dokumentation nach.
\e Escape; ASCII-Wert 27
\f Formfeed; ASCII-Wert 12
\n Linefeed; ASCII-Wert 10
\r Carriage Return; ASCII-Wert 13
\t Tabulator; ASCII-Wert 9
\xhh Ein Zeichen, dessen Wert in hexadezimaler Notation (Zahlensystem mit Basis 16) hh ist; \x09 wäre also der Tabulator und \x41 ist das Zeichen „A“. Die Hex-Zahl bezieht sich auf die Position des Zeichens in der ASCII-Tabelle. Für die Zeichen mit einer Position > 127 gilt die ANSI-Tabelle.
\ddd Ein Zeichen, dessen Wert in oktaler Notation (Zahlensystem mit Basis 8) ddd ist. Der Tabulator wäre also \011 und das „A“ \101.
\d Entspricht [0-9].
\D Ist das Komplement zu \d, entspricht also [^0-9].
\s Steht für jeden White-Space-Character (Leerzeichen, Tabulator).
\S Das Komplement zu \s, also alles, was kein White-Space-Character ist.
\w Jedes Zeichen, das als Word-Character betrachtet wird. Dieses entspricht der Sequenz „[0-9a-zA-Z_]“ (Alphanumerische Zeichen und der Unterstrich). Umlaute wie ä, ü oder das ß gehören nicht dazu!
\W Das Komplement zu \w.
\b Außerhalb von Sequenzen: Steht für eine Wortgrenze, d. h. auf einer Seite steht ein \w-Character und auf der anderen Seite ein \W-Character.
Innerhalb von Sequenzen: Backslash.
\B Das Komplement zu \b.
\A Beginn des Strings.
\Z Ende des Strings oder Newline.
\z Ende des Strings.

Die Zeichen im letzten Drittel der Tabelle dürfen mit Ausnahme des „\b“ nicht in Sequenzen verwendet werden. Sie sind sogenannte Assertions (Aussagen). Sie beziehen sich nicht auf ein einzelnes Zeichen, sondern machen eine Aussage über den Kontext zweier Zeichen. Bspw. matcht der Ausdruck „\w+\b\w+\b\w+“ nicht auf den Satz „Hamster ist klasse“. Das erste „\w+“ matcht zwar auf „Hamster“, dann müsste dem Ausdruck nach ein Zeichen der Klasse „\W“ kommen. Dies stimmt noch, da ein Space (Leerzeichen) folgt, dann aber erwarten wir wieder Zeichen der Klasse „\w“. Aber unser Space finden wir so nicht, da das „\b“ den Space nicht „einfing“. Als Hilfe könnten wir den Suchstring als „\w+\s\w+\s\w+“ schreiben. Jetzt fangen wir auch den Space.

„\A“, „\Z“ und „\z“ werden hier nicht weiter vertieft, da die Unterschiede zu „^“ bzw. „$“ für den Hamster unerheblich sind.

„^“ und „$“

Beides sind Assertions, wobei „^“ außerhalb von Sequenzen für den Beginn des Strings und „$“ für das Ende stehen. Innerhalb einer Sequenz bildet „^“ als erstes Zeichen das Komplement (also die umgekehrte Wirkung) der Sequenz, steht es nicht zuerst, fehlt ihm diese Metabedeutung. „$“ hat grundsätzlich keinerlei Metabedeutung in Sequenzen.

Eckige Klammern

Eine linke eckige Klammer „[“ kennzeichnet den Beginn einer Sequenz, die eine Characterklasse beschreibt und geht bis zur letzten rechten eckigen Klammer „]“, der keine linke Klammer entspricht. Eine rechte eckige Klammer allein hat keine Metabedeutung, eine linke Klammer muss mit einem Backslash maskiert werden. Innerhalb einer Sequenz kann eine rechte Klammer als erstes Zeichen stehen und muss nicht maskiert werden. „[]a-z]+“ matcht auf alphabetische Zeichen und die rechte Klammer.

Sequenzen

Innerhalb einer Sequenz dient der Bindestrich „-“ dazu, den Bereich der Sequenz anzugeben. Das Intervall ist beidseitig geschlossen, „[a-z]“ schließt also „a“ und „z“ mit ein. Um den Bindestrich selbst zu finden, schreibt man ihn einfach als erstes oder letztes Zeichen der Sequenz oder maskiert ihn mit einem Backslash. Sequenzen können auch mit den Oktalwerten (nicht vergessen: „\ddd“, mit d von 0 bis 7 gibt den Oktalwert eines Zeichens wieder) oder den Hexadezimalwerten („\xhh“, mit h von 0 bis F) der Zeichen notiert werden.

„\d“, „\D“, „\s“, „\S“, „\w“ und „\W“ können mit ihrer Metabedeutung in Sequenzen genutzt werden, „\b“ steht innerhalb von „[…]“ für den Backslash.

Das Pipe-Zeichen „|“

Wie wir oben sahen, steht „|“ für ein logisches Oder (dies ist ein inklusives Oder, es entspricht der schrecklichen Sprachkonstruktion „und/oder“. Bspw. ist ein Satz „Heute Abend koche ich oder lese das Buch zu Ende.“ in drei Fällen logisch wahr: Wenn ich nur koche, wenn ich nur lese, wenn ich koche und lese). Dieses Zeichen erlaubt es uns, verschiedene Alternativen für einen Match in einem Suchstring zu notieren. Mit Hilfe der runden Klammern „()“, können wir Subpattern bilden, die wir dann mit dem Pipezeichen verknüpfen.

Optionen der RegEx-Engine einstellen

Der RE-Engine kann man bestimmte Optionen zur allgemeinen Verarbeitung von Zeichenketten vorgeben. Diese Optionen sind in eine runde Klammer, beginnend mit einem Fragezeichen, gefolgt von den für die jeweilige Option stehenden Buchstaben, zu schreiben. Die Reichweite einer Option erstreckt sich auf das (Sub)Pattern, in dem sie enthalten ist. Ein Minuszeichen vor der Option kehrt dessen Bedeutung in das Gegenteil um.

Beispiel: „(?ms-ix)“ – Es wird „m“ und „s“ eingeschaltet, „i“ und „x“ ausgeschaltet. Das Minus bezieht sich immer auf alle Optionen, die dahinter aufgeführt sind.

Folgende Optionen existieren:
Option Bedeutung
i Groß- und Kleinschreibung werden ignoriert.
x Diese Option ermöglicht es, den Ausdruck durch Leerzeichen, Kommentare und Zeilenumbrüche in eine besser lesbare Form zu bringen. Im Hamster ist ein Zeilenumbruch damit aber nicht möglich. Deshalb ist es günstiger, auf diese Option zu verzichten. Statt dessen sollten Kommentare in der Form „(?#…)“ benutzt und Umbrüche innerhalb einer Filterzeile mit dem Unterstrich am Zeilenende gekennzeichnet werden.
m Ändert die Interpretation von „^“ und „$“ so, dass bei mehrzeiligen Texten auf Beginn und Ende einer einzelnen Zeile geprüft wird.
s Das Metazeichen „.“ (Punkt) matcht auch auf das Newline-Zeichen.
# Kommentare.

Achtung: Im Hamster ist standardmäßig die Option „i“ aktiviert, „m“, „s“ und „x“ sind deaktiviert. Um in einem Ausdruck nur groß- oder kleingeschriebene Buchstaben zu finden, muss deshalb die Option „(?-i)“ benutzt werden.

Kommentare

Ein Kommentar beginnt mit der Zeichenfolge „(?#“ und endet mit der schließenden runden Klammer „)“. Ist die Option „x“ der RE-Engine aktiv, so werden alle Zeichen nach dem Sonderzeichen „#“ außerhalb einer Zeichenklasse bis zum Zeilenende als Kommentar angesehen.

Quantifier

Quantifier sind Ausdrücke, die angeben, wie oft ein vorhergehender Ausdruck wiederholt werden darf oder muss. Wir haben schon „*“, „+“ und „?“ kennengelernt, diese sind eigentlich nur bequeme Kurzschreibweisen der allgemeinen Form eines Quantifiers: „{n,m}“, wobei dieser Ausdruck als „mindestens n Elemente und maximal m Elemente“ zu lesen ist; „{n,}“ heißt „minimal n und maximal unendlich viel Elemente“; „{n}“ heißt „genau n Elemente“. Unsere drei bekannten Quantifier entsprechen in dieser Notation also:

* = {0,}
+ = {1,}
? = {0,1}

Nach welchen Ausdrücken sind Quantifier erlaubt? Nach jedem einzelnen Character (sowohl escaped als auch nicht escaped), nach dem Punkt „.“ (wir erinnern uns, er steht für genau ein beliebiges Zeichen), nach einer Sequenz oder nach einem Subpattern (ein durch runde Klammern eingeschlossener Teil des Suchpatterns). Außerdem sind sie noch nach sogenannten Backreferences erlaubt, die hier aber nicht behandelt werden. Quantifier sind greedy, versuchen also den längstmöglichen Matchstring zu finden. Da dies nicht in allen Fällen gewünscht ist, kann man dem Quantifier direkt das Fragezeichen „?“ folgen lassen, dann wird der Quantifier genügsam und gibt sich mit dem kürzestmöglichen Matchstring zufrieden.

Quantifier sollten sehr mit Bedacht eingesetzt werden, da diese die Anzahl möglicher Kombinationen extrem erhöhen können, so dass der Hamster sehr lange braucht, um entscheiden zu können, ob ein Match vorliegt.

Back-References

Suchmuster, die in runden Klammern stehen, werden zwischengespeichert und können an anderer Stelle wiederverwendet werden, indem mit „\<Zahl>“ darauf Bezug genommen wird:

{(Holz|Plastik) und \1fenster}

Das Regex findet entweder „Holz“ oder „Plastik“ und speichert diesen Wert, weil er in einer runden Klammer steht. Dann wird das Wort „und“ gefunden. Wegen „\1“ wird der gespeicherte Inhalt der Klammer, zusammen mit „fenster“ zum Weitersuchen verwendet. Dadurch wird entweder „Holzfenster“ oder „Plastikfenster“ an dieser Stelle gefunden, je nachdem, welches der beiden Wörter weiter vorn gefunden wurde. Diese Regex findet also nur „Holz und Holzfenster“ oder „Plastik und Plastikfenster“, aber nicht „Holz und Plastikfenster“ oder „Plastik und Holzfenster“.

Der Rückbezug darf nicht in derselben Klammer stehen, auf die es sich bezieht:

{(a\1)}

Das führt nie zu einem positiven Ergebnis. Allerdings geht es, wenn sich ein Wiederholungszeichen dahinter befindet:

{(da|de\1)+}

findet „dadadada“ oder „dadeda“ oder auch „dadedadadada“.

Look-around-Assertion

Mit einer Look-around-Assertion kann getestet werden, ob ein Muster der gefundenen Stelle vorangeht oder folgt, ohne dass die geprüfte Zeichenkette in den gefundenen String übernommen wird. Als Beispiel soll die Buchstabenfolge „foo“ gefunden werden, die von der Zeichenfolge „bar“ gefolgt wird, ohne aber „bar“ im Suchergebnis wiederzufinden.

{foo(?=bar)}

Das Ergebnis lautet „foo“, im Gegensatz zu einer „normalen“ RegEx, bei der mit „{foobar}“ das Ergebnis auch „foobar“ lauten würde.

Es gibt vier Arten der Assertion:

?= vorwärts positiv („positive look-ahead assertion“)
?! vorwärts negativ („negative look-ahead assertion“)
?<= rückwärts positiv („positive look-behind assertion“)
?<! rückwärts negativ („negative look-behind assertion“)

Mit „{foo(?!bar)}“ lautet das Ergebnis nur dann „foo“, wenn „foo“ nicht von „bar“ gefolgt vorkommt, sondern z. B. das Wort „footer“.

Beispiele für rückwärtsgerichtete Assertion:

{(?<=foo)bar}“ findet „bar“ nur, wenn „foo“ davor kommt.

{(?<!foo)bar}“ findet „bar“ nur, wenn kein „foo“ davor steht.

Ein praktisches Beispiel – Suche nach Newsgruppen mit „.de.“ im Namen, aber nur, wenn kein „fr.“ davor steht (französische Gruppen können auch ein „.de.“ enthalten):

\.(?<!fr\.\S*)de\.

Konditionale Reguläre Ausdrücke

Eine weitere interessante Möglichkeit, um Assertionen anzuwenden, sind konditionale Reguläre Ausdrücke. Im Gegensatz zu der einfachen Assertion, die direkt mitentscheidet, ob der komplette Ausdruck matcht, lässt sich das hier im Sinne einer „if … then … else“-Konstellation relativieren. Der Aufbau ist folgender:

(?(if) then | else), dt.: (?(wenn) dann | sonst)

oder nur

(?(if) then), dt.: (?(wenn) dann)

Die Einleitung erfolgt immer mit einer geöffneten runden Klammer und einem Fragezeichen, gefolgt von einer „wenn“-Assertion, die nach den oberen Regeln aufgebaut ist. Dann folgen zwei Möglichkeiten, die mit einem Trennzeichen eingesetzt werden und mit einer sich schließenden Klammer enden. Je nach dem, wie der Test verläuft, wird dann die erste Möglichkeit bei positivem oder die zweite bei negativem Ergebnis durch die Regex-Engine ausgeführt. Ein Beispiel für eine Anwendung ist, wenn nur der Name des Absenders in den Match übernommen werden soll, ganz gleich, ob die alte oder neue Schreibweise vorhanden ist:

Suchstring entweder „Vorname Name <Mail@Adresse>“ oder „Mail@Adresse (Vorname Name)“

(?(?=.*<)[^<]*|[^\(]*\))

Die Assertion im konditionalen Regulären Ausdruck testet vorn, ob hier schon die neue Schreibweise angewandt wird, in dem sie eine geöffnete spitze Klammer sucht. Wenn dies der Fall ist, wird die erste, sonst die andere Variante genommen. Da der konditionale Reguläre Ausdruck hier allein steht, würde er auch nach diesem Muster „(?(?=<)…“ (ohne „.*“) die geöffnete spitze Klammer finden, wir hätten dann aber keine Möglichkeit, den vorderen Namen noch mit der ersten Variante durch ein Match zu greifen, da der interne Pointer in diesem Fall schon daran vorbei ist (z.B. (?(?=<).*) auf „test <123>“).

Leider haben wir noch das Problem, dass der Name noch nicht sauber abgetrennt ist. Entweder endet er noch mit einem Leerzeichen oder mit einer zu schließenden runden Klammer. Als Bonus für Fortgeschrittene, können wir hier noch je eine weitere Assertion im Ergebnisausdruck mit einbauen, um das zu korrigieren:

(?(?=.*<).*\w(?=\s*<)|[^\(]*\w(?=\)))

Wie wir bereits oben gelernt haben, kann man mit einer einfachen Assertion testen, ob ihr bestimmte Zeichen folgen, ohne sie in den Match zu übernehmen. Und genau das passiert hier ebenfalls, wir haben also eine Kombination von einem klassischen konditionalen Regulären Ausdruck mit je einer normalen Assertion im Ergebnismatch. Außerdem kann durch das Einfügen von „\w“ gleich noch auf alphanumerische Zeichen getestet werden, so dass es bei nicht vorhandenen Namen keinen Leersting als Ergebnis gibt, sondern ein False.

Möglichkeiten und Beispiele für Reguläre Ausdrücke

Quantifier

Die einfachsten Beispiele sind die Quantifier „*“, „+“, „?“ und „{…}“. Sie wirken auf das Element, das ihnen vorangeht, was z. B. ein Buchstabe sein kann.

*“ bedeutet, dass ein Zeichen 0 mal oder öfter gefunden wird:
abc*“ findet unter anderem „ab“, „abc“ und „abccccc“.

+“ bedeutet, dass ein Zeichen 1 mal oder öfters gefunden wird:
abc+“ findet unter anderem „abc“ und „abccccc“, aber nicht „ab“.

?“ bedeutet, dass ein Zeichen 0 oder 1 mal gefunden wird:
abc?“ findet „ab“ und „abc“, aber nicht „abccccc“.

{n}“ bedeutet, dass ein Zeichen n mal gefunden wird:
abc{3}“ findet nur „abccc“.

{n,}“ bedeutet, dass ein Zeichen mindestens n mal gefunden wird:
abc{3,}“ findet unter anderem „abccc“ und „abccccc“, aber nicht „abcc“.

{n,m}“ bedeutet, dass ein Zeichen mindestens n und höchstens m mal gefunden wird:
abc{3,4}“ findet nur „abccc“ und „abcccc“, aber nicht „abcc“ oder „abccccc“.

Zeichenklassen

.“ enthält alle Zeichen, kann alles darstellen:
... “ findet alles, was 3 Zeichen lang ist (auch 3 Leerzeichen) und von Leerzeichen eingerahmt ist.

\w“ enthält alle alphanumerischen Zeichen (A…Z, a…z, 1…9 und den Unterstrich „_“):
\w{3}“ findet unter anderem „123“, „ich“, „wir“ und „A_B“.

\W“ enthält alle Zeichen, die nicht alphanumerisch sind:
\W{3}“ findet unter anderem „///“, „---„ und „|+|“.

\s“ findet ein „white space“ (Leerzeichen, Tabulator, Newline, Return):
a\sa“ findet unter anderem „a a“.

\S“ findet alles, was kein „white space“ ist:
\S+\s\S+“ findet unter anderem „Hallo du“, aber nicht „A_A“.

\d“ findet alle Ziffern (0…9):
„\d{3}“ findet alle 3-stelligen Zahlen.

\D“ findet alle Zeichen, die keine Zahlen sind:
\d-\D+“ findet unter anderem „3-stellig“.

[ab]“ bedeutet, dass an dieser Stelle die Zeichen „a“ und „b“ vorkommen können:
[ab]{3}“ findet: „aaa“, „aba“, „aab“, „abb“, „bbb“, "bab", „bba“ und „baa“

Das Zeichen „-“ kennzeichnet innerhalb von „[]“einen Bereich von Zeichen:
[A-Z]“ findet jeden Buchstaben zwischen „A“ und „Z“ inkl „A“ und „Z“.

Weitere Möglichkeiten

\b“ ist die Grenze zwischen „\w“ und „\W“ (also eine Wortgrenze):
Hall.\b findet „Hallo du!“ und „Hallo, …“, aber nicht „Hallöle“.

^“ ist der Anfang einer Zeichenkette:
Im String „Hallo, Du halber Halbling!“ wird mit „^Hal..“ nur „Hallo“ gefunden.

$“ ist das Ende einer Zeichenkette:
\s+$“ sucht nach (den meist überflüssigen) Leerzeichen am Zeilenende,
^$“ sucht nach Leerzeilen.

Reguläre Ausdrücke testen

Zum Testen von Regulären Ausdrücken existiert im Hamster-Skriptarchiv (siehe Linkliste) ein Skript „Regexp.hsc“ von Karl Pflästerer.

Freeware zum Testen Regulärer Ausdrücke: