Abk.: Regex

Hilfe:Regular Expressions

aus Wiki Aventurica, dem DSA-Fanprojekt
Version vom 4. Juli 2024, 12:06 Uhr von StipenTreublatt (Diskussion | Beiträge) (→‎Metazeichen: Hinweis auf neue Erkenntnis - das hat uns schon lange Probleme gemacht.)
(Unterschied) ← Nächstältere Version | Zeige aktuelle Version an (Unterschied) | Nächstjüngere Version → (Unterschied)

Andere Sprachversionen: Fehler beim Erstellen des Vorschaubildes: Die Miniaturansicht konnte nicht am vorgesehenen Ort gespeichert werden Wikipedia: regular expressions Regulärer Ausdruck

Einführung[Quelltext bearbeiten]

Mit Regulären Ausdrücken kann man Mengen von Zeichenketten definieren. Jede zur Menge gehörige Zeichenkette erfüllt dabei gewisse Voraussetzungen, die von dem regulären Ausdruck festgelegt wird. Eine häufige Anwendung sind "Suchen und Ersetzen"-Funktionen, die nicht nur feste Zeichenketten, sondern auch reguläre Ausdrücke suchen können.

Beispiel in Worten

Gesucht sind Zeichenketten, die mit Ver anfangen und mit ung enden. Zu dieser Menge gehören Worte wie Vergebung und Verbreitung.

Unix-Syntax[Quelltext 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, viele Sprachen haben allerdings auch noch darüber hinausgehende Funktionen, die sich in ihrer Syntax unterscheiden können.

Metazeichen[Quelltext bearbeiten]

Metazeichen haben in einer Regex eine besondere Bedeutung; soll explizit nach einem solchen Zeichen gesucht werden, muss ein \ vorangestellt werden, um das Metazeichen zu "entwerten" ("escape"); Beispiel: \. sucht nach dem Zeichen . (während . nach allen Zeichen bis auf Zeilenumbrüche sucht - also unter anderem auch nach . ... hier kann man leicht Fehler machen).

Im Folgenden eine einfache Liste der Metazeichen, ihre Funktion wird in den nächsten Abschnitten beschrieben:

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

Achtung: In der #dplreplace-Funktion von DPL muss außerdem noch das Zeichen ' "entwertet" werden (siehe z.B. Vorlage:Kickit; Grund derzeit unbekannt).

Einzelzeichen[Quelltext bearbeiten]

Code Bedeutung Beispiel
. jedes Zeichen außer Zeilenumbruch P.nkt passt auf "Punkt" und "Pünkt", aber auch auf "Pankt", "Penkt" sowie viele weiteren Zeichenketten.
\ Metazeichen entwerten Punkt\. passt auf "Punkt." Möchte man nach "\" suchen, muss dies selbst entwertet werden: \\.
^ Anfang der Zeichenkette ^Anfang passt nur auf "Anfang", wenn es am Anfang der Zeichenkette steht. Kann durch den Modifikator m verändert werden, sodass auch der Anfang von Zeilen passt. Nicht mit der Negierung in Mengenklammern verwechseln.
$ Ende der Zeichenkette Ende$ passt nur auf "Ende", wenn es am Ende der Zeichenkette steht. Kann durch den Modifikator m verändert werden, sodass auch das Ende von Zeilen passt.
\A Anfang der Zeichenkette \AAnfang passt nur auf "Anfang", wenn es am Anfang der Zeichenkette steht. Kann nicht durch Modifikator m verändert werden.
\Z Ende der Zeichenkette Ende\Z passt nur auf "Ende", wenn es am Ende der Zeichenkette steht.
\b Wortgrenze \bwende\b passt nur auf "wende", wenn es als einzelnes Wort steht, also nicht auf "verwende", "wenden", oder "verwenden".
\B keine Wortgrenze \Bwende\B passt auf "verwenden", nicht aber auf "verwende", "wenden", oder "wende".

Klammern[Quelltext bearbeiten]

Code Bedeutung Beispiel
[ ] Mengenklammern: definiert eine Menge von Zeichen, die an dieser Stelle passen; siehe auch #Zeichenklassen M[ae][iy]er passt auf "Maier", "Meier", "Mayer" und "Meyer" (nicht aber auf Mayr; dazu müsste M[ae][iy]e?r gesucht werden)
[^ ] Negierung in Mengenklammern [^ ] passt auf jedes Zeichen außer dem Leerzeichen; [^\.] passt auf jedes Zeichen außer dem Punkt. Nicht mit dem Zeichenkettenanfang verwechseln.
{ } Anzahlklammern siehe #Quantoren
( ) Gruppierung Gruppierungen können mittels #Quantoren als Ganzes beeinflusst werden; in einer "Suchen und Ersetzen"-Funktion können sie zudem verwendet werden, um Zeichenketten in die Ausgabe einzuspeisen.
( | ) Oder-Verknüpfung in Gruppierung (Borbarad|Nandussohn|Sphärenschänder) passt auf mehrere Namen dieser Person; in MediaWiki muss das Pipe-Zeichen gewöhnlicherweise mittels {{!}} angegeben werden, da der Parser es sonst als Beginn eines neuen Parameters oder als Teil einer Tabellensyntax interpretiert.

Zeichenklassen[Quelltext bearbeiten]

Zeichenklassen sind vordefinierte Mengen von Zeichen. Mittels #Quantoren kann angegeben werden, wie oft Zeichen der Zeichenklasse in der Regex vorkommen dürfen.

Zeichenklasse Bedeutung Beispiel
\s Whitespace, entspricht [ \t\n\r\f\v] (Leerzeichen, Tabulator, Newline, Carriage Return, Formfeed, vertical Tab)
\S keine Whitespaces, entspricht [^ \t\n\r\f\v]
\d Ziffern, entspricht [0-9] \d\d\d passt auf alle dreistelligen Zahlen
\D keine Ziffern, entspricht [^0-9] \D\d\D passt auf alle Ziffern, die nicht von Ziffern umschlossen sind
\w Wortzeichen (alphanumerische Zeichen und Unterstrich), entspricht [a-zA-Z0-9_]; je nach LOCALE auch nicht-lateinische Buchstaben wie z.B. Umlaute \s\w\w\w\s passt auf alle dreistelligen Buchstaben/Ziffern-Kombinationen, die von Whitespace umgeben sind.
\W kein Wortzeichen (keine alphanumerische Zeichen, kein Unterstrich), entspricht [^a-zA-Z0-9_] \w\W\w passt auf zwei Wortzeichen, die durch ein Nicht-Wortzeichen getrennt sind.

Quantoren[Quelltext bearbeiten]

Quantoren legen fest, wie oft der vorangestellte Ausdruck in der Zeichenkette vorkommen kann. "Ausdruck" bezieht sich hier entweder auf einzelne Zeichen, #Zeichenklassen, Zeichenmengen ([]), oder auf Gruppierungen (()).

Code Bedeutung Beispiel
{n,m} Ausdruck muss mindestens n-mal und höchtens m-mal vorkommen. a{0,2}ber passt auf "ber", "aber", und "aaber".
{n} Ausdruck muss genau n-mal vorkommen, entspricht {n,n}. [ae]{2}ber passt auf "aaber", "aeber", "eaber" und "eeber".
{n,} Ausdruck muss mindestens n-mal vorkommen. [a]{2,}ber passt auf "aaber", "aaaber", ...
? Ausdruck ist optional, entspricht {0,1}. Nicht verwechseln mit #Modifikatoren und #Look-around. a?ber passt auf "ber" und "aber".
+ Ausdruck muss mindestens einmal vorkommen, entspricht {1,}. a+ber passt auf "aber", "aaber", "aaaber", ...
* Ausdruck darf beliebig oft vorkommen, entspricht {0,}. a*ber passt auf "ber", "aber", "aaber", "aaaber", ...

Quantoren werden standardmäßig maximiert ("gieriges" Verhalten): T.*123 wählt auf Text123Fest123 angewendet die gesamte Zeichenkette aus.

Mittels ? kann dies auf "genügsames" Verhalten umgeschaltet werden: T.*?123 wählt auf Text123Fest123 angewendet nur "Text123" aus.

Erweiterte Funktionen[Quelltext bearbeiten]

Je nach Implementierung gibt es weitere Funktionen; für uns relevant sind die Implementierungen in Python (Dokumentation, für Bot-Skripte) sowie in php (Dokumentation, für DPL und RegexFunctions).

Look-around[Quelltext bearbeiten]

Mit den folgenden Funktionen kann man die Umgebung einer Zeichenkette in die Regex miteinbeziehen, ohne dass diese Umgebung selbst in der Ausgabe verwendet wird.

Syntax Bedeutung Zusatzinfo
(?= ) Inhalt der Funktion muss auf den Fund folgen ("positive Lookahead-Assertion") Affe(?=nmensch) passt auf "Affe", wenn danach "nmensch" steht.
(?! ) Inhalt der Funktion darf nicht auf den Fund folgen ("negative Lookahead-Assertion") Affe(?!nmensch) passt auf "Affe", wenn danach nicht "nmensch" steht.
(?<= ) Inhalt der Funktion muss vor dem Fund stehen ("positive Lookbehind-Assertion") (?<=Affen)mensch passt auf "mensch", wenn davor "Affen" steht.
(?<! ) Inhalt der Funktion darf nicht vor dem Fund stehen ("negative Lookbehind-Assertion") (?<!Affen)mensch passt auf "mensch", wenn davor nicht "Affen" steht.

Modifikatoren[Quelltext bearbeiten]

Modifikatoren können das Verhalten der gesamten Regex verändern, oder auch nur das Verhalten einer Gruppierung.

Syntax Bedeutung
(?Modifikatoren)Ausdruck modifiziert das Verhalten der gesamten Regex
(?Modifikatoren:Gruppierung)Ausdruck modifiziert das Verhalten der Gruppierung
Modifikator Bedeutung Beispiel
i Groß-/Kleinschreibung wird ignoriert. (?i:h)eute passt auf "heute" und "Heute". (?i)ai passt auf "AI", "ai", "Ai" und "aI".
m ^ und $ beziehen sich auf Zeilenanfang bzw. -ende ("multiline-Modus"). (?m)^Anfang passt auf "Anfang", wenn es am Anfang der Zeichenkette oder direkt nach einem Zeilenumbruch steht.
s . passt auch auf Zeilenumbrüche ("singleline-Modus"). (?s)<!--.*?--> passt auf alle HTML-Kommentare, auch wenn Zeilenumbrüche enthalten sind.

Suchen und Ersetzen[Quelltext bearbeiten]

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

Im Wiki Aventurica sind mehrere Parser-Funktionen installiert, die Suche & Ersetze-Befehle ausführen (siehe auch Hilfe:Variable#Funktionen_2):

  • #replace: (simple Ersetzung, keine Regex möglich)
  • #dplreplace: (Ersetzung mittels Regex)
  • #rreplace: (Ersetzung mittels Regex)

Desweiteren gibt es noch ein paar weitere Funktionen, die reguläre Ausdrücke verwenden:

  • #rmatch: (Bedingte Anweisung aufgrund einer Suche mittels Regex)
  • #rsplit: (Aufteilung einer Zeichenkette aufgrund einer Suche mittels Regex)
Originaltext Code Ersetzter Text Kommentar
Fluss ist Singular, Flüsse Plural. Flusse ist falsch.
{{#replace: <Text>
|Fluss|Bach}}
Bach ist Singular, Flüsse Plural. Bache ist falsch. Wegen dem Umlaut wird "Flüsse" nicht ersetzt, hier bräuchte man eine Regex.
Mittelreicher sind im Allgemeinen nicht reich. Garetier leben vor allem im Neuen Reich.
{{#dplreplace: <Text>
|(Mittelreicher{{!}}Garetier)|Mittelländer}}
Mittelländer sind im Allgemeinen nicht reich. Mittelländer leben vor allem im Neuen Reich. Das "oder" kann nicht mittels | angegeben werden, da dies vom MediaWiki-Parser als Beginn eines neuen Parameters aufgefasst würde. Stattdessen verwendet man das "magische Wort" {{!}}.
Drachenlachen tief im Rachen.
{{#dplreplace: <Text>
|(Drachen)(lachen)|\1diener \2 }}
Drachendiener lachen tief im Rachen. Gruppierungen können mittels \<Zahl> in die Ausgabe eingefügt werden.
Beute für die Leute kommt noch heute, nicht erst übermorgen.
{{#dplreplace: <Text>
|(\we\w*e)|'''\1'''}}
Beute für die Leute kommt noch heute, nicht erst übermorgen. Wenn wir nur Worte auswählen wollen, die mit <beliebiger Buchstabe>e beginnen, müssen wir uns etwas einfallen lassen...
Beute für die Leute kommt noch heute, nicht erst übermorgen.
{{#dplreplace: <Text>
|[ ](\we\w*e)| '''\1'''}}
Beute für dieLeute kommt nochheute, nicht erst übermorgen. Versuch mit Leerzeichen, funktioniert nicht, da Leerzeichen am Anfang und Ende eines Parameters vom MediaWiki-Parser automatisch weggekürzt werden.
Beute für die Leute kommt noch heute, nicht erst übermorgen.
{{#dplreplace: <Text>
|[ ](\we\w*e)|\99 '''\1'''}}
Beute für die Leute kommt noch heute, nicht erst übermorgen. Dieser Versuch funktioniert besser, da die Gruppe "99" nicht vorhanden ist, und daher nichts eingefügt wird. Aber es ist immer noch nicht optimal, das Wort am Satzanfang wird nicht gefunden.
Beute für die Leute kommt noch heute, nicht erst übermorgen.
{{#dplreplace: <Text>
|\b(\we\w*e)\b|'''\1'''}}
Beute für die Leute kommt noch heute, nicht erst übermorgen. Mittels \b für "Wortgrenze" haben wir endlich die Lösung gefunden.
Heute heißt heute, nicht erst morgen.
{{#dplreplace: <Text>
|\b(?i)(h)eute\b|'''\1eute'''}}
Heute heißt heute, nicht erst morgen. Modifikator (?i) schaltet die Unterscheidung zwischen Groß- und Kleinschreibung für die folgende Gruppe aus.
Übermorgen muss ich mir etwas borgen.
{{#dplreplace: <Text>
|(\w*orgen)|''\1''}}
Übermorgen muss ich mir etwas borgen. Das erste Wort wird nicht richtig markiert, weil die Umlaute nicht zu \w gehören.
Übermorgen muss ich mir etwas borgen.
{{#dplreplace: <Text>
|([\wüÜ]*orgen)|'''\1'''}}
Übermorgen muss ich mir etwas borgen. Wenn man die Umlaute explizit dazuschreibt, funktioniert es.
Dieser Satz hat kein Ende
{{#dplreplace: <Text>
|^(.*)kein(.*[^\.])$|\1ein\2.}}
Dieser Satz hat ein Ende. ^ markiert den Anfang der Zeichenkette, $ das Zeilenende. [^\.] bedeutet "alles außer Punkt", das ^ in der Mengenklammer bedeutet dabei die Negierung des Folgenden.
  • Drachen sind groß.
  • Drachen sind magisch.*
  • Drachen sind gefährlich.
{{#dplreplace: <Text>
|^\*|#}}
  1. Drachen sind groß.
  • Drachen sind magisch.*
  • Drachen sind gefährlich.
Funktioniert nicht, da nur der Anfang der Zeichenkette betrachtet wird.
  • Drachen sind groß.
  • Drachen sind magisch.*
  • Drachen sind gefährlich.
{{#dplreplace: <Text>
|\*|#}}
  1. Drachen sind groß.
  2. Drachen sind magisch.#
  3. Drachen sind gefährlich.
Funktioniert nicht, da jeder Stern im Text ersetzt wird.
  • Drachen sind groß.
  • Drachen sind magisch.*
  • Drachen sind gefährlich.
{{#dplreplace: <Text>
|(?m)^\*|#}}
  1. Drachen sind groß.
  2. Drachen sind magisch.*
  3. Drachen sind gefährlich.
Mit (?m) wird jede Zeile als eigene Zeichenkette angesehen, und hat daher auch jeweils einen Zeichenkettenanfang, den wir auswählen können.

Weblinks[Quelltext bearbeiten]

  • 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