Dieser Artikel ist veraltet. Einige Dinge haben sich seit der Erstellung des Artikels womöglich geändert. Ein regulärer Ausdruck (//oder Regex/RegExp, wie er auch genannt wird//) ist ein formelähnlicher Ausdruck, der eine Menge in einer Zeichenkette definiert. ======Nutzen====== Der Nutzen von regulären Ausdrücken ist die Filtermöglichkeit. Mithilfe von regulären Ausdrücken lassen sich (//vergleichsweise unkompliziert//) komplexe Filter zusammenstellen. Insbesondere in der Programmentwicklung werden reguläre Ausdrücke häufig als mächtige Werkzeuge verwendet - in nahezu jeder Programmiersprache ist die Möglichkeit, reguläre Ausdrücke zu verwenden, gegeben, beispielsweise: * Perl / Python / Ruby * C * Java * .NET-Framework Einige Textverarbeitungstools (//wie beispielsweise **ed** und **grep**//) und auch Office-Suiten (//z.B. **OpenOffice**//) unterstützen reguläre Ausdrücke, sodass es beispielsweise möglich ist, bestimmte immer wieder vorkommende Textteile mithilfe einer Regel zu finden und zu ersetzen. Ein Beispiel hierfür wäre: Alle IP-Adressen der Liste herausfiltern Bewerkstelligen ließe sich dies mit folgendem regulären Ausdruck [\b(?:\d{1,3\.){3}\d{1,3}\b]* (//zugegeben das ist ein etwas exotischeres Beispiel und sieht ein wenig verwirrend aus!//). ======Auswahl====== Das wohl wichtigste Element von regulären Ausdrücken ist die Definition einer **Zeichenauswahl**. Mithilfe dieser wird definiert, was genau gesucht wird - beispielsweise ein bestimmter Buchstabe, ein spezieller Bereich,... Eine Auswahl wird stets in eckigen Klammern angegeben, beispielweise: ^Ausdruck ^ Effekt/Auswahl ^ | **[abc]** | eines der Zeichen //a//, //b// oder //c// | |**[a-z]** | eines der Zeichen der Menge //a// bis //z// | |**[a-zA-Z0-9]** | eines der Zeichen der Mengen //a// bis //z//, //A// bis //Z// und //0// bis //9// | Der Ausdruck **[abc]** würde also auf die Zeichenkette "//bac//" passen, aber nicht auf: "//def//" oder auch: "//BAC//", da reguläre Ausdrücke **case-sensitive** (//Unterscheidung zwischen Groß- und Kleinschreibung//) sind. =====Bereiche===== Es lassen sich nicht nur einzelne Folgen angeben, auch ganze Bereiche lassen sich definieren. Will man nun beispielsweise einen beliebigen Buchstaben aus dem Alphabet in einen Ausdruck aufnehmen, liese sich dieser - wie im vorherigen Abschnitt erläutert - wie folgt definieren: [abcdefghijklmnopqrstuvwxyz] einfacher und zeitsparender wäre allerdings: [a-z] Der Ausdruck gibt die Menge "//von a bis z//" an. Das Ganze funktioniert übrigens ebenso mit Zahlen: [666-1337] Hier würde die Zahlenmenge "//von 666 bis 1337//" in das Filterkriterium des regulären Ausdrucks fallen. =====Kombination===== Auswahlbereiche lassen sich auch kombinieren. Sinnvoll wäre das beispielsweise bei folgender Filterung: Zeige alle Einträge, die eine Ziffer oder einen Buchstaben des Alphabets enthalten. Daraus würde sich ergeben: [a-zA-Z0-9] Die drei Mengen **0-9**, **a-z** und **A-Z** werden hier einfach aneinander gehängt. Für einen Buchstaben des Alphabets wurden hier zwei Mengen (//a-z und A-Z//) definiert, da reguläre Ausdrücke, wie bereits erwähnt, case-sensitive sind und für Groß- und Kleinschreibung zwei Mengen definiert werden müssen. ======Spezifikation====== Alleine mit den bisher bekannten Auswahlausdrücke sind reguläre Ausdrücke nicht sonderlich nützlich - sie lassen sich aber noch genauer spezifizieren. =====Negierung===== Ausdrücke lassen sich durch die Verwendung eines Zirkumflexes (**^**) ganz leicht negieren - dazu ein praktikables Beispiel: Gesucht werden alle Einträge, die keine Ziffer enthalten Die Lösung wäre hier: [^0-9] Steht das Zirkumflex vor einer Mengendefinition, wie hier bei **0-9**, so definiert das Zirkumflex eine **Negierung** (//Verneinung, Invertierung//). =====Suchbereich===== Die bisher gezeigten Ausdrücke haben die gesamte Zeichenkette durchsucht, was aber nur der Anfang/das Ende einer Zeichenkette interessant ist? =====Anfang===== Die Beschränkung auf den Anfang eines Strings wird mithilfe des Zeichens "**^**" vor der Mengendefinition deklariert. Beispiel: Zeige alle Mitarbeiter, deren Vorname nicht mit A oder B beginnt: Anton Ahnungslos Benny Bauer Donny Abas Hier ließe sich einfach überprüfen, ob die Zeichenfolge mit "**A**" oder "**B**" beginnt und somit eine Auswahl treffen - wir bedienen uns also der vorhin erläuterten Negierung: ^[^AB] Der Ausdruck "//matcht//" auf alles was nicht mit "//A//" oder "//B//" anfängt. Das **^** vor den eckigen Klammern definiert, dass der folgende Ausdruck am Anfang der Zeichenkette **NICHT** vorkommen darf. Einzig gültiger Name wäre hier "//Donny Abas//", da alle anderen Vornamen mit A oder B beginnen. =====Ende===== Wenn nur das Ende einer Zeichenkette interessant ist, muss dies mit einem "//$//" am Ende definiert werden - Beispiel: Zeige alle Mitarbeiter, deren Name nicht mit "//t//" endet: Schmit Schmitt Schmidt Schmid Die Lösung wäre hier: [^t]$ Das Name "//Schmid//" würde hier als einziger übrig bleiben, da alle anderen Namen mit einem "//t//" enden. =====Quantoren===== Quantoren, bzw. Quantifizierer sind so Zeichen, die einen vorher definierten Ausdruck wiederholen und so mehrfach für eine Zeichenkette zulassen. Ein Beispiel wäre: Zeige alle Mitarbeiter, deren Vor- bzw Nachname nicht den Buchstaben "**s**" bzw. "**S**" enthält: Paul Salem Siegfried Golem Antonio Hilem Die Lösung hierfür ist: ^[^Ss]* Der Stern am Ende sagt aus, dass der Ausdruck beliebig oft (oder gar nicht!) für die Zeichekette gültig ist - stünde er nicht, würde lediglich das erste Zeichen überprüft werden. Beim Beispiel wäre das: * **P**aul Salem * **S**iegfried Golem * **A**ntonio Hilem Hier würde also auch "//Paul Salem//" übrigbleiben, was im Sinne der Zielsetzung semantisch inkorrekt wäre. Weitere Quantoren sind: ^Ausdruck^Effekt/Auswahl^ |**?** |Optional, der Ausdruck kann einmal oder gar nicht vorkommen | |**+** |Der Ausdruck kann einmal oder beliebig oft vorkommen | |***** |Der Ausdruck kann beliebig oft oder gar nicht vorkommen | |**{x}**|Der Ausdruck muss **exakt x-mal** vorkommen | |**{x,}**|Der Ausdruck muss **mindestens x-mal** vorkommen | |**{x,y}**|Der Ausdruck muss **mindestens x-mal** und darf **höchstens y-mal** vorkommen| ======Vordefinierte Ausdrücke und Klassen====== Es gibt bereits eine nicht zu verachtende Liste an vordefinierten Ausdrücken, welche verwendet werden können: ^Ausdruck^Effekt/Auswahl^ |**\d**|eine Ziffer, also //[0-9]//| |**\D**|ein Zeichen - keine Ziffer, also //[^\d]//| |**\w**|ein Buchstaben, ein Unterstrich oder eine Ziffer, also //[a-zA-Z_0-9]//| |**\W**|ein Zeichen, das **kein** Buchstabe, Ziffer oder ein Unterstrich ist, also //[^\w]//| |**\s**|sogeannter Whitespace, also ein Leer- oder unsichtbares Steuerzeichen| |**\S**|ein Zeichen, das **kein** Leer- oder Steuerzeichen ist, also //[^\s]//| |**\b**|leere Zeichenkette am Anfang oder Ende| |**\B**|leere Zeichenkette, die **nicht** am Anfang oder Ende des Wortes steht| |**\<**|leere Zeichenkette am Wortanfang| |**\>**|leere Zeichenkette am Wortende| |**\n**|Zeilenumbruch (//Unix//)| |**\r\n**|Zeilenumbruch (//Windows//)| Die meisten Applikationen unterstützen diese Ausdrücke - im Zweifelsfall gibt allerdings die Manpage oder Handbuch Aufschluss darüber, ob sie unterstützt werden. POSIX hat in den neueren Implementationen weitere Klassen vorgesehen - diese werden aber nicht von jeder Anwendung oder Programmiersprache unterstützt: ^Ausdruck^Klasse/Auswahl^ |**[:digit:]**|Eine Ziffer| |**[:xdigit:]**|Hexadezimale Ziffern| |**[:alnum:]**|Alphanumerische Zeichen| |**[:alpha:]**|Buchstaben| |**[:upper:]**|Großbuchstaben| |**[:lower:]**|Kleinbuchstaben| |**[:graph:]**|Buchstaben oder Satzzeichen| |**[:print:]**|Druckbare Zeichen, also alles außer Whitespaces und Steuerzeichen| |**[:punct:]**|Satz- und Sonderzeichen| |**[:space:]**|jegliche Absätze, Vorschübe oder Leerzeichen| |**[:blank:]**|Absätze oder Leerzeichen| |**[:cntrl:]**|(//unsichtbare//) Steuerzeichen| ======Beispiele====== =====exotischere Beispiele===== ====Filterung nach String==== Zeige alle Mitarbeiter, die **nicht** Paul heißen: Paul Panter Paul Panzer Paul Pali Anton Ahnungslos Falsch wäre der Ansatz: [^Paul]* Die Begründung ist einfach, "//Paul//" wird hier nicht als Textfolge angesehen - der Ausdruck versteht hierunter die Buchstaben "//P//", "//a//", "//u//" und "//l//". Deswegen wird auch der semantisch korrekte "//Anton Ahnungslos//" herausgefiltert, da sein Name die Buchstaben "//u//" und "//l//" enthält. Die Lösung wäre: ^((?!Paul).)* Der Ausdruck bedient sich einer sogenannten "//Look-around assertion//"...(to be filled) ======Lernprogramm====== {{ :computer:RegexCoach.jpg?200|Der Regex Coach zeigt die "//Matches//" eines Ausdrucks an}} Sehr interessant und empfehlenswert ist das Programm "//Regex Coach//". Es dient dazu, die Arbeitsweise von regulären Ausdrücken besser zu verstehen. So können beispielsweise Zeichenfolgen und reguläre Ausdrücke eingegeben werden, der Coach hebt dann die Bereiche, die vom Ausdruck erfasst werden, hervor. Auf Wunsch hin wird die Vorgehensweise des regulären Ausdrucks auch schrittweise angezeigt - das ist insbesondere bei verschachtelten Ausdrücken äußerst hilfsreich. Der Regex Coach ist ein kostenloses Programm, er kann unter folgender URL bezogen werden: http://www.weitz.de/regex-coach In meinen Augen ist der Regex Coach ein erstklassiges Tool bei der Erlernung von regulären Ausdrücken, auch wenn es die von POSIX implementierten Zeichenklassen (//noch?//) nicht unterstützt. ======Merkblatt====== Ich habe die hier erläuterte Thematik auf zwei Seiten komprimiert zusammengefasst - ideal für die Pinnwand im Büro. Das PDF kann hier bezogen werden: {{:computer:regex_auf_zwei_seiten.pdf|RegEx auf zwei Seiten}} ======Internetverweise====== * RegEx Coach, Programm zum Erlernen von Regex: http://www.weitz.de/regex-coach * Webauftritt mit Behandlung von Sonderfällen, etc: http://www.regular-expressions.info * SelfHTML-Artikel zu regulären Ausdrücken: http://de.selfhtml.org/perl/sprache/regexpr.htm * Regular Expressions - User guide: http://www.zytrax.com/tech/web/regex.htm * Regex-Howto: http://www.amk.ca/python/howto/regex * Regex auf zwei Seiten: {{:computer:regex_auf_zwei_seiten.pdf|RegEx auf zwei Seiten}}