Hilfe:Regular Expressions

aus Wiki Aventurica, dem DSA-Fanprojekt
Wechseln zu: Navigation, Suche

Einführung[Bearbeiten]

Mit Regulären Ausdrücken (engl. regular expressions; kurz RegExps) kann man Mengen von Zeichenketten definieren. Die zur Menge gehörigen Zeichenketten müssen dabei eine bestimmte gemeinsame Struktur haben. Diese Struktur wird mittels einer RegExp beschrieben.

Beispiel in Worten

Die Zeichenketten müssen mit Ver anfangen und mit ung enden. Zu dieser Menge gehören Worte wie Vergebung und Verbreitung.

Unix-Syntax[Bearbeiten]

Die weiteste Verbreitung zur Definition von Regulären Ausdrücken hat die Unix-Syntax. Sie kommt in nahezu allen Implementierungen für die diversen Programmiersprachen zum Einsatz. Abweichend davon haben viele Sprachen noch darüber hinausgehende Features die sich in ihrer Syntax unterscheiden können.

Metazeichen[Bearbeiten]

Metazeichen sind Zeichen die nicht für sich selbst stehen, sondern denen eine besondere Bedeutung zukommt. Will man dennoch eines dieser Zeichen zur Einschränkung der Zeichenmenge verwenden, so muss es mit einem vorangestellten \ geschrieben (entwertet engl. escaped) werden.

. ^ $ * + ? { } [ ] \ | ( )

Funktionen[Bearbeiten]

Metazeichen Bedeutung Beispiel
. jedes Zeichen
(ausser Zeilenumbrüche)
Bekannter Anfang.*?bekanntes Ende
^ Anfangsmarkierung ^Passt nur wenn's am String-Anfang steht
$ Ende-Markierung Passt nur wenn's am String-Ende steht$
* 0 oder beliebiges Vorkommen des vorangegangenen Zeichens/Gruppe (entspricht {0,} ) ah* passt auf jeden beliebig langen Geistesblitz
(ah, ahh, ahhhhhhhhh, auch auf a)
+ 1 oder beliebiges Vorkommen des vorangegangenen Zeichens/Gruppe (entspricht {1,} ) ah+ passt auf jeden beliebig langen Geistesblitz
(ah, ahh, ahhhhhhhhh, nicht aber a)
? 0 oder 1 Vorkommen (entspricht {0,1} )
alternativ: + oder * auf "nicht-gierig" umschalten
Zwerge? passt auf Zwerg oder Zwerge
Elf(en)? passt auf Elf oder Elfen
{ } Anzahlklammern
[ ] Mengenklammern (definiert eine Menge von Zeichen die an der Stelle passen) M[ae][iy]er passt auf Maier, Meier, Mayer und Meyer
(nicht aber auf Mayr; dann müsste M[ae][iy]e?r stehen)
^ Negierung in "Mengenklammern"
(muss am Anfang stehen)
[^ ] passt auf jedes Zeichen ausser dem Leerzeichen
[^A-Za-z0-9] passt auf jedes Zeichen das kein Groß- oder Kleinbuchstabe oder eine Ziffer ist
\ Metazeichen entwerten \| passt auf | und \[ passt auf [
| Oder-Verknüpfung Borbarad|Nandussohn|Sphärenschänder passt auf mehrere Namen dieser Person
(Tipp: immer mit ( ) umklammern um böse Überraschungen zu vermeiden)
( ) konsumierend gruppieren
Weitere interessante Zeichen(kombinationen)
\t \n \r \f \v Tabulator, Newline, Carriage Return, Formfeed, vertical Tab)
\d = [0-9]. Zahlen
\D = [^0-9]. keine Zahlen
\s = [ \t\n\r\f\v]. Whitespace
\S = [^ \t\n\r\f\v]. keine Whitespaces
\w = [a-zA-Z0-9_]. Wort - abhängig von LOCALE auch Umlaute etc.
(alphanumerische Zeichen und Unterstrich)
\W = [^a-zA-Z0-9_]. kein Wort - abhängig von LOCALE auch Umlaute etc.
(keine alphanumerische Zeichen, kein Unterstrich)
\A Anfang des Strings, unabhängig von MULTILINE
\b Wortgrenze (ACHTUNG: unbedingt als r"\b" verarbeiten, da "\b" bereits Backspace in Python bedeutet!)
\B keine Wortgrenze
\z
\Z Ende des Strings, unabhängig von MULTILINE

Python-Syntax[Bearbeiten]

Python unterstützt die Definitionsregeln der Unix-Syntax und zusätzlich noch einige spezielle Features.

Die offizielle Dokumentation gibt's unter http://docs.python.org/library/re.html.


Ausgewählte Features
Syntax Bedeutung Zusatzinfo
(?<=String_ohne_Metazeichen) positive Lookbehind-Assertion (?<=Affen)mensch passt auf mensch wenn davor Affen steht.
(?<!String_ohne_Metazeichen) negative Lookbehind-Assertion (?<!Affen)mensch passt auf mensch wenn davor nicht Affen steht.
(?=String_ohne_Metazeichen) positive Lookahead-Assertion Affe(?=nmensch) passt auf Affe wenn danach nmensch steht.
(?!String_ohne_Metazeichen) negative Lookahead-Assertion Affe(?!nmensch) passt auf Affe wenn danach nicht nmensch steht.
Einschaltung globaler RegExp-Optionen
(?iLmsux) i (ignore case) (?i)blabla passt auf blabla wobei Groß-/Kleinschreibung keine Rolle spielt
L (locale dependent) Spezialitäten der lokalen Sprache werden berücksichtigt; z.B. passt (?L)ü nicht mehr auf ue
m (multi-line) ^ und $ beziehen sich jeweils auf Zeilenanfang und -ende nicht auf den Stringanfang- und -ende
s (Punkt passt auf alles) (?s)<!--.*?--> passt auf alle HTML-Kommentare, auch wenn dieser Zeilenumbrüche beinhaltet.
u (unicode dependent) \w und Ähnliches passt auch auf Unicode-Zeichen

(ist bei replace.py immer schon vorbesetzt)

x (verbose) erlaubt "schönere" Definitionen mit Kommentaren etc.

Beispiele[Bearbeiten]

siehe auch Hilfe:Robots/Dokumentation zu replace.py#Beispiele für "Suche und Ersetze"-Beispiele mit Regulären Ausdrücken (-regex)

Das Wiki Aventurica hat zwei Parser-Funktionen, mit denen Suche & Ersetze-Befehle möglich sind: {{#replace: }} und {{#dplreplace: }}, wobei nur letztere reguläre Ausdrücke erlaubt.
Die Syntax bei beiden Funktionen ist ansonsten gleich: Hinter den Doppelpunkt kommt der zu untersuchende Text, als erster Parameter wird der Suche-Ausdruck angegeben und als zweiter Parameter der Ersetze-Ausdruck:
{{#(dpl)replace: TEXT | SUCHE | ERSETZE MIT }}

Einfache Wortersetzung MädchenGirl
Das blonde Mädchen ist hübscher als das brunette Mädle, aber nicht so schön wie das rothaarige Mädel. {{#replace: ... |Mädchen|Girl}}

Das blonde Girl ist hübscher als das brunette Mädle, aber nicht so schön wie das rothaarige Mädel.

Die {{#replace: ... }}-Funktion kann keine regulären Ausdrücke verarbeiten, sondern nur echten Text. Die {{#dplreplace: … }}-Funktion hingegen beherrscht reguläre Ausdrücke, da die Wiki-Syntax aber | stets als Trennungszeichen einer Parser-Funktion interpretiert, muss man stattdessen {{!}} schreiben.
Im Folgenden seien nun alle Beispiele auf die {{#dplreplace: … }}-Funktion bezogen.
Originaltext Code Ersetzter Text Kommentar
Konsumierte Gruppen mit verschiedenen möglichen Werten
Das blonde Mädchen ist hübscher als das brunette Mädle, aber nicht so schön wie das rothaarige Mädel. {{# … |(Mädchen{{!}}Mädle{{!}}Mädel)|Babe}}

Das blonde Babe ist hübscher als das brunette Babe, aber nicht so schön wie das rothaarige Babe.

Der Ausdruck (Mädchen{{!}}Mädle{{!}}Mädel) trifft nun auf alle 3 Schreibweisen zu und ersetzt diese mit Babe.
Reguläre Ersetzung konsumierter Gruppen mit eingefügtem "el"
Das blonde Mädchen ist hübscher als das brunette Mädchen, aber nicht so schön wie das rothaarige Mädchen. {{# … |(Mäd)(chen)|\1el\2}}

Das blonde Mädelchen ist hübscher als das brunette Mädelchen, aber nicht so schön wie das rothaarige Mädelchen.

Mit den Ausdrücken \1 \2 \3, ... fügt man die 1., 2., 3., ... konsumierte Gruppe ( ) aus dem Suche-Ausdruck wieder ein.
Reguläre Ersetzung Zeichenketten mit b(beliebige Buchstaben)e ⇒ fett
Das blonde Mädchen ist hübscher als das brunette Mädchen, aber nicht so schön wie das rothaarige Mädchen. {{# … |b(\w*)e|'''b\1e'''}}

Das blonde Mädchen ist hübscher als das brunette Mädchen, aber nicht so schön wie das rothaarige Mädchen.

Leider trifft dieser Code auch auf Text innerhalb eines Wortes zu. Um dies zu vermeiden muss man sich etwas einfallen lassen, z.B. ein Leerzeichen vorne und hinten anzufügen, wie im folgenden Beispiel.
Reguläre Ersetzung Zeichenketten mit Leerzeichen-b-(beliebige Buchstaben)-e-Leerzeichen ⇒ fett
Das blonde Mädchen ist hübscher als das brunette Mädchen, aber nicht so schön wie das rothaarige Mädchen. {{# … |[ ]b(\w*)e[ ]| '''b\1e''' }}

DasblondeMädchen ist hübscher als dasbrunetteMädchen, aber nicht so schön wie das rothaarige Mädchen.

Der Fehler der nicht wiedereingefügten Leerzeichen rührt aus der Tatsache, dass Whitespace am Anfang und Ende von Funktionsausdrücken durch die Wiki-Syntax ignoriert wird, weswegen Leerzeichen an diesen Stellen anders geschrieben werden müssen, wie im folgenden Beispiel.
Reguläre Ersetzung Zeichenketten mit Leerzeichen-b-(beliebige Buchstaben)-e-Leerzeichen ⇒ fett
Das blonde Mädchen ist hübscher als das brunette Mädchen, aber nicht so schön wie das rothaarige Mädchen. {{# … |[ ]b(\w*)e[ ]|\99 '''b\1e''' \99}}

Das blonde Mädchen ist hübscher als das brunette Mädchen, aber nicht so schön wie das rothaarige Mädchen.

Im Suche-Ausdruck kann man einfach [ ] verwenden; beim Ersetze-Ausdruck kann man zwar die HTML-Codierung &#32; nutzen, aber besser ist es mit \99 o.ä. eine nicht-vorhandene konsumierte Gruppe einzufügen, da nun keine Leerzeichen an Anfang und Ende des Ausdrucks stehen.
Reguläre Ersetzung Zeichenketten mit Leerzeichen-b-(beliebige Buchstaben)-e-Leerzeichen ⇒ fett
Blonde Mädchen sind hübscher als brunette Mädchen, aber nicht so schön wie rothaarige Mädchen. {{# … |[ ]([Bb])(\w*)e[ ]|\99 '''\1\2e''' \99}}

Blonde Mädchen sind hübscher als brunette Mädchen, aber nicht so schön wie rothaarige Mädchen.

Obwohl wir mit ([Bb]) eine Menge definiert haben, die auf B und b zutrifft, hilft das hier nicht, da dem großen B kein Leerzeichen vorausgeht. Um dennoch nur ganze Wörter zu ersetzen, wählen wir im folgenden Beispiel den Code für Wortgrenze \b.
Reguläre Ersetzung Zeichenketten mit Leerzeichen-b-(beliebige Buchstaben)-e-Leerzeichen ⇒ fett
Blonde Mädchen sind hübscher als brunette Mädchen, aber nicht so schön wie rothaarige Mädchen. {{# … |\b(?i)(b)(\w*)e\b|'''\1\2e'''}}

Blonde Mädchen sind hübscher als brunette Mädchen, aber nicht so schön wie rothaarige Mädchen.

\b markiert Wortgrenzen. Gleichzeitig nutzen wir nun auch (?i) um für die folgende Gruppe (b) die Groß-/Kleinschreibung zu ignorieren, statt ([Bb]) zu schreiben.
Reguläre Ersetzung jedes Wortes, dem ein Leerzeichen vorausgeht ⇒ kursiv
Das blonde Mädchen ist hübscher als das brunette Mädchen, aber nicht so schön wie das rothaarige Mädchen. {{# … |(?<= )(\w+)|''\1''}}

Das blonde Mädchen ist hübscher als das brunette Mädchen, aber nicht so schön wie das rothaarige Mädchen.

Der Fehler hier liegt darin, dass die Sonderzeichen Ä ä Ö ö Ü ü ß u.ä. nicht zu \w gehören.
Reguläre Ersetzung jedes Wortes ⇒ kursiv
Das blonde Mädchen ist hübscher als das brunette Mädchen, aber nicht so schön wie das rothaarige Mädchen. {{# … |(?<= )((?i)[\wäöü]+)|''\1''}}

Das blonde Mädchen ist hübscher als das brunette Mädchen, aber nicht so schön wie das rothaarige Mädchen.

Daher definieren wir eine Zeichenmenge [\wäöü], die neben \w auch die Umlaute enthält. Das Ignorieren der Groß-Kleinschreibung ist zwar hier nicht notwendig, aber Ä Ö Ü würden als Großschreibung unserer Zeichen ä ö ü erkannt werden.
Setzen eines Punktes, falls keiner am Satzende steht
Das blonde Mädchen ist hübscher als das brunette Mädchen, aber nicht so schön wie das rothaarige Mädchen {{# … |([^\.])$|\1.}}

Das blonde Mädchen ist hübscher als das brunette Mädchen, aber nicht so schön wie das rothaarige Mädchen.

[^\.] meint "alles außer Punkt"; das Metazeichen . muss dabei durch ein \ entwertet werden
Multi-Line Ersetzung
  • Das brunette Mädchen ist hübsch.
  • Das blonde Mädchen ist hübscher.
  • Das rothaarige Mädchen ist am hübschesten.
{{# … |(?m)^\*|#}}
  1. Das brunette Mädchen ist hübsch.
  2. Das blonde Mädchen ist hübscher.
  3. Das rothaarige Mädchen ist am hübschesten.
(?m)^\* trifft jeden Zeilenanfang mit *, nicht nur den Stringanfang und ersetzt * mit #.

Links[Bearbeiten]

Externe Links[Bearbeiten]

RegExp-Tools[Bearbeiten]

Damit man die RegExps ohne großen Aufwand ausprobieren kann, gibt es ein paar Software-Tools.

  • Kodos (OpenSource, funktioniert unter Win9x/ME/2k/XP und Linux) - ein RegExp-Editor, mit dem man vollwertigen Python-Code erzeugen kann. Alle Eingaben inkl. der Suchtexte (!) können in einer Textdatei abgespeichert und diese später wieder eingelesen werden; damit ist auch ein Austausch hier über das Wiki möglich.
  • RegEx-Coach (ClosedSource, privat kostenlos für Win9x/ME/2k/XP) - ein RegExp-Editor, der im WYSIWYG-Verfahren das Testen von RegExps ermöglicht. Funktioniert ähnlich wie Kodos, man kann aber nicht so gut abspeichern, geschweige denn Python-Code erzeugen. Hat dennoch ein paar interessante Funktionen, die Kodos fehlen.
  • txt2regex (bash-Skript für POSIX) zum einfachen Erzeugen von RegExps. Man wird wie in einem Expertensystem interaktiv abgefragt, was man gesucht haben möchte und Stück für Stück wird dann eine RegExp daraus geformt. Diese wird gleichzeitig für 6 Sprachen angezeigt. Damit ist es sehr gut geeignet, um die SpamRegex ohne Detailwissen anpassen zu können. Siehe den Bildschirmauszug:
  • Visual Regex (ein Tcl/Tk-Skript, platformunabhängig) - visuelle RegExps darstellen und erzeugen