Reguläre Ausdrücke – für einen einfachen Umgang mit Zeichenketten
Wenn Sie sich tiefer mit der Informatik beschäftigen, dann sind Sie eventuell bereits einmal auf den Begriff „regulärer Ausdruck“ gestoßen – häufig auch auf Englisch als regular expression oder abgekürzt als Regex bezeichnet. Dieser kommt in vielen Programmiersprachen, in Datenbanksprachen und auch in verschiedenen Texteditoren zum Einsatz, um bestimmte Zeichenketten zu definieren. Reguläre Ausdrücke sind ausgesprochen nützlich, um Texte auszuwerten. Auf diese Weise können Sie beispielsweise deren Inhalte automatisch ermitteln oder Eingaben des Anwenders eines Programms aufnehmen. Reguläre Ausdrücke zeichnen sich hierbei durch eine hohe Flexibilität aus, sodass Sie damit die vielfältigen Ausdrucksformen der natürlichen Sprache berücksichtigen können.
Wozu dient ein regulärer Ausdruck?
Wenn Sie Zeichenketten in einer Programmiersprache oder für eine Datenbankabfrage verwenden, kommen hierbei normalerweise exakte Vergleiche zum Einsatz. Das bedeutet, dass Sie nur überprüfen können, ob diese Zeichenkette mit einer bestimmten anderen Zeichenkette genau übereinstimmt. Darüber hinaus bieten Ihnen viele Programmiersprachen noch weitere Funktionen an – beispielsweise um die Position eines bestimmten Teilbereichs zu bestimmen oder um zu überprüfen, ob eine bestimmte Zeichenkette in einem größeren Text vorkommt. Diese Möglichkeiten sind bei zahlreichen Aufgaben jedoch nicht ausreichend – oder würde einen enormen Aufwand mit sich bringen. Das liegt daran, dass sich die menschliche Sprache – und damit auch Texte – durch zahlreiche Variationen auszeichnet. Für den menschlichen Leser sind diese leicht zu erkennen und einzuordnen. Für ein Computerprogramm ist es jedoch sehr schwierig, den entsprechenden Inhalt zu erkennen.
Als Beispiel hierfür können Sie sich vorstellen, dass Sie mit einem automatischen Programm überprüfen möchten, ob sich ein Link in einem Text befindet. Wenn Sie diesen durchlesen, sollte diese Aufgabe sicherlich kein großes Problem darstellen, da Sie den Aufbau eines Links kennen und diesen daher schnell identifizieren können. Wenn Ihr Programm diese Aufgabe erledigen soll, stellt dies jedoch eine erhebliche Herausforderung dar. Das liegt daran, dass es viele verschiedene Möglichkeiten gibt, um einen Link darzustellen. Beispielsweise ist es möglich, zu Beginn die sogenannte Schema-Bezeichnung anzugeben – wie etwa http, https oder ftp. Viele Anwender verzichten in einem gewöhnlichen Text jedoch darauf. Das Gleiche ist bei der Angabe www der Fall. Die eigentliche Adresse ist bei einem Link frei wählbar. Schließlich müssen Sie die Endung – die sogenannte Top-Level-Domain – angeben. Auch hierfür stehen viele verschiedene Möglichkeiten zur Auswahl. Darüber hinaus ist es in einem Link möglich, auf verschiedene Unterseiten zu verlinken. Wenn Sie all diese Optionen anhand gewöhnlicher Zeichenketten überprüfen möchten, ist hierfür ein ausgesprochen umfangreiches Programm erforderlich. Mit regulären Ausdrücken können Sie die entsprechenden Vorgaben und die Auswahlmöglichkeiten jedoch deutlich kompakter zusammenfassen. Das erleichtert die Auswertung von Texten deutlich.
Zusammengefasst ist es mit einem regulären Ausdruck möglich, ein bestimmtes Schema für eine Zeichenkette zu erstellen, das vielfältige Optionen einschließt. Mit einem Computerprogramm können Sie dann überprüfen, ob ein Text einen Ausdruck enthält, der diesem Schema entspricht. Auch weitere Aktionen sind möglich – beispielsweise dessen Position zu ermitteln, oder ihn aus dem Text auszuschneiden. Bei Datenbankabfragen können Sie alle Einträge abrufen, die diese Vorgaben erfüllen. In Texteditoren dienen reguläre Ausdrücke häufig der Suchen-und-Ersetzen-Funktion. Damit können Sie alle Textbereiche, die dem entsprechenden Schema entsprechen, durch einen anderen Ausdruck ersetzen.
Welche Techniken unterstützen reguläre Ausdrücke?
Die Anwendungsmöglichkeiten für reguläre Ausdrücke sind sehr vielfältig. Sie können diese in fast allen gängigen modernen Programmiersprachen verwenden – beispielsweise in Python, Java, JavaScript, PHP, C, C++, Perl und Ruby. Hinzu kommen die Sprachen des .NET-Frameworks – also in erster Linie C# und Visual Basic. Das zeigt, dass reguläre Ausdrücke ein sehr breites Anwendungsgebiet im Bereich der Softwareentwicklung bieten.
Damit sind die Möglichkeiten jedoch noch nicht abgeschlossen. Reguläre Ausdrücke finden beispielsweise auch häufig beim Umgang mit Datenbanken Verwendung. Fast alle Datenbanksysteme unterstützen diese. Auch viele Texteditoren und weitere Werkzeuge für die Textverarbeitung erlauben den Einsatz dieser Technik. Außerdem spielt sie eine wichtige Rolle für viele Suchmaschinen. Hierbei dient sie jedoch nur der internen Umsetzung, sodass der Anwender nicht in direkten Kontakt mit regulären Ausdrücken kommt.
Die Festlegung der Syntaxregeln
Die Idee, reguläre Ausdrücke zu verwenden, ist bereits seit vielen Jahrzehnten verbreitet. Erstmals formulierte sie der Mathematiker Stephen Kleene in den 50er Jahren. Dabei verwendete er jedoch noch eine andere Schreibweise als heute gebräuchlich. Im Laufe der Zeit wurde dieses Prinzip auch für die Informatik immer wichtiger.
Ein großes Problem bestand jedoch darin, dass es hierbei keine einheitlichen Regeln für die Schreibweise und für die Bedeutung der verschiedenen Zeichen gab. Bis heute gibt es hierfür keinen offiziellen Standard. Allerdings entwarfen die Entwickler der Programmiersprache Perl für die Version 5.0, die 1994 erschien, ein umfangreiches Regelwerk für die Syntax regulärer Ausdrücke. Diese Festlegung war so hilfreich, dass sie auch anderen Programmiersprachen als Vorbild diente. Auf diese Weise entstand der Ausdruck „Perl Compatible Regular Expressions“. Dabei handelt es sich um konkrete Vorgaben für die Syntax regulärer Ausdrücke, die sich an der Umsetzung in Perl 5.0 orientiert. Diese haben sich so weit durchgesetzt, dass alle gängigen Programmiersprachen dieses Regelwerk umsetzen. Allerdings gibt es nach wie vor einige Abweichungen und Erweiterungen dazu.
Die wichtigsten Grundregeln für die Bildung regulärer Ausdrücke
Mit regulären Ausdrücken ist es möglich, bestimmte Regeln für Zeichenketten vorzugeben. Das Programm kann daraufhin überprüfen, ob ein bestimmter Text oder ein Ausdruck die vorgegebenen Regeln erfüllt. Dabei ist es möglich, sehr vielfältige Vorgaben zu machen. Das erleichtert die Bearbeitung von Zeichenketten deutlich. Die folgenden Abschnitte stellen die wichtigsten Möglichkeiten vor, mit denen sich reguläre Ausdrücke formulieren lassen.
Zeichenliterale
Zeichenliterale sind die Zeichen, die exakt in der vorgegebenen Weise in der entsprechenden Zeichenkette vorhanden sein müssen. Auf diese Weise können wir beispielsweise überprüfen, ob der Buchstabe ‚a‘ in einer Zeichenkette vorhanden ist. Dazu müssen wir diesen in genau dieser Form als regulären Ausdruck formulieren: a.
Das trifft auf viele verschiedene Zeichenketten zu. Alle folgenden Beispiele erfüllen diese Bedingung:
- „Hallo“
- „Mayer“
- „Hier steht ein langer Text.“
Dabei ist es auch möglich, mehrere Buchstaben oder Zeichen in den regulären Ausdruck zu stellen. Wenn wir hier beispielsweise die Kombination al angeben, erfüllt nur das erste der angegebenen Beispiele diese Bedingung. In den übrigen beiden Zeichenketten kommt diese Buchstabenkombination nicht in der entsprechenden Form vor.
Falls die verwendete Kombination mehrfach im entsprechenden Text auftritt, bezieht sich der reguläre Ausdruck nur auf die erste Übereinstimmung. Das ist beispielsweise wichtig, wenn wir die Position bestimmen wollen.
Metazeichen mit spezieller Bedeutung
Wenn wir lediglich Zeichenliterale verwenden, bringt dies im Vergleich zu den gewöhnlichen Methoden für die Bearbeitung von Zeichenketten noch keine Vorteile mit sich. Reguläre Ausdrücke bieten jedoch noch viele weitere Möglichkeiten. Um diese zu markieren, kommen sogenannte Metazeichen zum Einsatz. Wenn eines dieser Metazeichen in unserem regulären Ausdruck auftaucht, überprüft das Programm daher nicht, ob dieses Zeichen im entsprechenden Text vorkommt – so wie dies bei einem Zeichenliteral der Fall wäre. Stattdessen wird die zugehörige Funktion ausgeführt. Die einzelnen Möglichkeiten hierfür werden im weiteren Verlauf noch angesprochen. Vorerst ist es lediglich wichtig, die Metazeichen zu identifizieren. Dabei handelt es sich um die folgenden 12 Zeichen – wobei wir öffnende und schließende Klammer jeweils zusammengefasst haben, da diese eine feste Einheit bilden:
- [ und ]
- ( und )
- { und }
- |
- ?
- +
- –
- *
- ^
- $
- \
- .
Manchmal kommt es auch vor, dass wir überprüfen wollen, ob eines dieser zwölf Metazeichen in unserer Zeichenkette vorkommt. In diesem Fall müssen wir deutlich machen, dass es sich hierbei nicht um ein Metazeichen handelt, das mit einer speziellen Funktion verknüpft ist, sondern um ein Zeichenliteral. Zu diesem Zweck müssen wir dem entsprechenden Ausdruck den Rückwärts-Schrägstrich (Backslash) voranstellen. Wenn wir beispielsweise überprüfen wollen, ob das Pluszeichen in einem Text auftritt, benötigen wir hierfür den folgenden Ausdruck: \+. Auch dieser Ausdruck lässt sich mit anderen Zeichen verbinden. Mit dem Ausdruck 1+1 können wir beispielsweise überprüfen, ob die Zeichenfolge „1+1“ in unserem Text vorhanden ist.
Eine bestimmte Auswahl für ein Zeichen erstellen
Eine sehr praktische Möglichkeit besteht darin, verschiedene Auswahlmöglichkeiten für eine bestimmte Textstelle vorzugeben. Das bedeutet dass das Zeichen, das an dieser Stelle steht, mit einem der in der Auswahl angegebenen Zeichen übereinstimmen muss. Dazu müssen wir die verschiedenen Möglichkeiten in eine eckige Klammer schreiben. Als Beispiel hierfür gehen wir davon aus, dass wir in einer Liste eine Person mit dem Nachnamen Mayer suchen. Wir sind uns allerdings nicht sicher, welche Schreibweise der entsprechende Nachname aufweist – es wäre auch die Schreibweise „Maier“ möglich. Um beide Alternativen abzufragen, fügen wir einfach die beiden Buchstaben in eine eckige Klammer ein: Ma[yi]er.
Hierbei ist es auch möglich, bestimmte Bereiche zu verwenden. Das ist insbesondere bei Zahlen sinnvoll. Dazu müssen wir den Anfangs- und den Endpunkt des entsprechenden Bereichs mit einem Bindestrich verbinden. Wenn wir beispielsweise alle Zahlen zwischen 33 und 38 abfragen wollen, wäre dies mit dem folgenden Ausdruck möglich: 3[3-8]. Diese Schreibweise ist auch bei Buchstaben möglich. In diesem Fall bezieht sie sich auf die alphabetische Reihenfolge. Der Ausdruck [c-f] umfasst beispielsweise die Buchstaben c, d, e und f.
Schließlich ist es auch möglich, ein bestimmtes Zeichen auszuschließen. Zu diesem Zweck verwenden wir das Zirkumflex-Zeichen. Wenn wir beispielsweise alle Ausdrücke akzeptieren wollen, die mit „Ma“ beginnen, bei denen daraufhin genau ein weiterer Buchstabe folgt und die mit der Buchstabenfolge „er“ enden, außer den Nachnamen „Maler“, können wir dies wie folgt festlegen: Ma[^l]er. Dieser Ausdruck würde beispielsweise sowohl auf die Namen Mayer als auch Maier zutreffen, aber auch auf andere Kombinationen wie beispielsweise Ma&er – nicht jedoch auf den Begriff Maler.
Der Punkt als Platzhalter für ein beliebiges Zeichen
Eine weitere Möglichkeit stellt es dar, einen Platzhalter zu verwenden. Hierzu dient der Punkt. Dafür können wir jedes beliebige Zeichen einsetzen. Der Ausdruck Ma.er trifft daher auf die Namen Mayer, Maier und Maler zu, genauso wie auf viele weitere Zeichenketten wie Ma&er oder Ma5er. Dabei müssen wir lediglich beachten, dass der Punkt für genau ein Zeichen steht. Diese Anzahl dürfen wir weder über- noch unterschreiten. Daher sind Ausdrücke wie Maurer oder Maer nicht inbegriffen.
Zeichenklassen
Darüber hinaus können wir bei regulären Ausdrücken sogenannte Zeichenklassen verwenden. Ein Beispiel hierfür ist der Ausdruck \d. Dieser umfasst alle Ziffern zwischen 0 und 9. Von großer Bedeutung ist auch die Zeichenklasse \w. Diese umfasst alle Buchstaben, Ziffern und den Unterstrich. Darüber hinaus gibt es noch einige weitere Möglichkeiten. Die folgende Tabelle stellt diese dar:
- \d Ziffern zwischen 0 und 9
- \D Alle Zeichen, bei denen es sich nicht um Ziffern handelt
- \w Ziffern, Buchstaben und der Unterstrich
- \W Alle Zeichen, bei denen es sich weder um Ziffern noch um Buchstaben oder den Unterstrich handelt
- \s Leerzeichen, Zeilenumbrüche, Tabulator etc.
- \S Alle Zeichen, die nicht in \s inbegriffen sind
Mehrere Alternativen vorgeben
Wenn wir mehrere Alternativen für einzelne Buchstaben vorgeben möchten, können wir diese in eckige Klammern schreiben. Es ist jedoch auch möglich, Alternativen für größere Bestandteile vorzugeben. Dazu müssen wir die Alternativen mit einem senkrechten Strich trennen. Falls wir beispielsweise Internetadressen in einem Text suchen, ist es sinnvoll, zu überprüfen, ob diese die Endung de oder com aufweisen: de|com.
In der Regel ist es hierbei empfehlenswert, mit Klammern deutlich zu machen, welche Bereiche die entsprechenden Alternativen umfassen. Wenn wir beispielsweise auch überprüfen wollen, ob vor der entsprechenden Endung ein Punkt (den wir mit dem Backslash als Zeichenliteral auszeichnen müssen) steht, wäre dies mit dem folgenden Ausdruck möglich: \.(de|com).
Dabei können wir auch mehrere Optionen eingeben. Wenn wir beispielsweise nicht nur die Endungen de und com, sondern auch org, net und info abfragen wollen, ist dies mit dem folgenden Ausdruck möglich: \.(de|com|org|net|info).
Optionale Zeichen
Eine weitere Möglichkeit besteht darin, ein optionales Zeichen vorzugeben. Das bedeutet, dass der Ausdruck auf Zeichenketten zutrifft – unabhängig davon ob das entsprechende Zeichen vorhanden ist oder nicht. Dazu müssen wir nach dem entsprechenden Zeichen ein Fragezeichen einfügen. Auf diese Weise können wir bei der bereits vorgestellten Überprüfung der Nachnamen auch einen Ausdruck bestimmen, der sowohl auf die Schreibweise Maier als auch auf die Kurzschreibweise Mair zutrifft: Maie?r.
Wenn wir mehrere Zeichen als optional kennzeichnen wollen, ist es möglich, diese in eine Klammer zu schreiben. Das ist beispielsweise bei der Überprüfung von Internetadressen hilfreich. Hierbei wissen wir häufig nicht, ob diese den Zusatz www verwenden. Mit dem folgenden Ausdruck fragen wir sowohl die Adresse www.beispiel.com als auch beispiel.com ab: (www\.)?beispiel\.com.
Die Position festlegen
Eine weitere Möglichkeit besteht darin, die Position des Ausdrucks festzulegen. Dazu verwenden wir sogenannte Anker. Hierfür können wir wieder das Zirkumflex-Zeichen verwenden – das in diesem Fall aber eine ganz andere Funktionsweise als bei der Verneinung einer Zeichenfolge hat. Wenn wir dieses Zeichen zu Beginn einfügen, bedeutet dies, dass die Zeichenkette mit dem entsprechenden Ausdruck beginnen muss. Wenn wir beispielsweise den Ausdruck ^Mayer verwenden, ist dieser in der Zeichenkette „Mayer, Sebastian“ enthalten, nicht jedoch in „Sebastian Mayer“.
Auf ähnliche Weise können wir das Ende eines Ausdrucks markieren. Hierfür verwenden wir das Dollarzeichen. Dieses bedeutet, dass die Zeichenkette mit dem entsprechenden Begriff enden muss. Auf diese Weise ist es auch möglich, den Inhalt ganz genau zu bestimmen. Wenn wir beispielsweise nur Einträge suchen wollen, die exakt mit dem Begriff „Mayer“ übereinstimmen – ohne jegliche Zusätze – müssen wir jeweils am Anfang und am Ende einen Anker setzen: ^Mayer$.
Wiederholungen
Reguläre Ausdrücke ermöglichen es auch, bestimmte Bereiche zu wiederholen. Hierfür kommen verschiedene Zeichen zum Einsatz, die jeweils eine unterschiedliche Bedeutung haben. Beispielsweise ist es möglich, das Sternzeichen zu verwenden. Dieses bedeutet, dass sich der entsprechende Ausdruck in einer unbestimmten Anzahl wiederholen darf. Diese kann jedoch auch bei 0 liegen. Das bedeutet, dass es nicht notwendig ist, dass der entsprechende Ausdruck vorkommt. Wenn wir beispielsweise Internetadressen abfragen wollen, könnten wir den folgenden Ausdruck verwenden: www\.[a-zA-Z0-9]*\.de. Dieser umfasst beliebige Adressen mit dem Zusatz www und der Endung de. Dazwischen können beliebige Buchstaben und Ziffern stehen – in einer beliebigen Anzahl. Allerdings umfasst dieser Ausdruck weder den Unter- noch den Bindestrich, sodass er einige Möglichkeiten, die eigentlich gültig wären, ausschließt. Das bedeutet, dass hierbei Adressen wie www.beispiel.de, www.neuesBeispiel.de oder www.nochEinBeispiel.de enthalten sind – aber auch ungültige Werte wie www..de.
Eine weitere Möglichkeit stellt das Pluszeichen dar. Dieses erlaubt ebenfalls eine beliebige Wiederholung. Allerdings wird dabei der Wert 0 ausgeschlossen. Das heißt, dass mindestens eines der möglichen Zeichen auftreten muss. Der Ausdruck www\.[a-zA-Z0-9]+\.de umfasst daher ebenfalls alle oben genannten Beispiele – mit Ausnahme des Begriffs www..de.
Darüber hinaus ist es möglich, präzisere Vorgaben für die Ausdrücke zu machen. Beispielsweise ist es möglich, eine genaue Vorgabe für die Anzahl der Wiederholungen zu machen. Dazu müssen Sie die Anzahl in eine geschweifte Klammer schreiben. Der Ausdruck www\.[a-zA-Z0-9]{3}\.de umfasst beispielsweise nur die Adressen, die drei Buchstaben verwenden – wie etwa www.xxl.de oder www.css.de. Darüber hinaus ist es möglich, einen Wertebereich vorzugeben. Wenn Sie beispielsweise alle Seiten suchen möchten, deren Adresse zwischen 3 und 6 Buchstaben enthält, können Sie hierfür den folgenden Ausdruck verwenden: www\.[a-zA-Z0-9]{3-6}\.de.
Reguläre Ausdrücke und Wildcards
In der Informatik sind neben regulären Ausdrücken auch Wildcards als Platzhalter verbreitet. Viele Programmiersprachen und Datenbanksysteme unterstützen diese Technik ebenfalls, sodass Sie sich häufig frei entscheiden können, welche dieser Möglichkeiten Sie verwenden. Daher ist es sinnvoll, kurz zu vergleichen, worin der Unterschied besteht.
Wildcards dienen lediglich als Platzhalter. Dabei ist es üblich, ein Zeichen wie den Unterstrich oder das Fragezeichen für einen einzelnen Buchstaben zu verwenden. Das Sternsymbol dient hingegen in der Regel als Platzhalter für eine beliebig lange Zeichenkette. Darüber hinaus unterstützen viele Systeme das Rautezeichen als Platzhalter für einen nummerischen Wert. Genaue Angaben zur Länge oder zu den Zeichen, die an der entsprechenden Stelle stehen können, sind bei Wildcards jedoch nicht möglich.
Das bedeutet, dass Wildcards deutlich weniger Möglichkeiten als reguläre Ausdrücke bieten, um eine Zeichenkette genau zu bestimmen. Das bringt jedoch den Vorteil mit sich, dass sie einfacher anzuwenden sind. Wenn ein einfacher Platzhalter bei Ihrer Anwendung seinen Zweck erfüllt, ist es daher sinnvoll, mit Wildcards zu arbeiten. Sind hingegen genauere Vorgaben erforderlich, müssen Sie reguläre Ausdrücke verwenden.
Darüber hinaus sollten Sie beachten, dass die Umsetzung der Wildcards nicht immer festen Regeln folgt. Verschiedene Datenbanksysteme und Programmiersprachen verwenden hierbei unterschiedliche Symbole. Daher ist hierbei stets eine genaue Einarbeitung erforderlich.
Fazit: Reguläre Ausdrücke ermöglichen einen effizienten Umgang mit Zeichenketten
Die Ausführungen in diesem Artikel haben gezeigt, dass es mit regulären Ausdrücken möglich ist, genaue Vorgaben für eine Zeichenkette zu machen. Das erlaubt es, bestimmte Inhalte aus einem Text auszuwerten oder Datenbankeinträge zu finden, ohne dass hierfür der exakte Ausdruck erforderlich ist. Mit regulären Ausdrücken ist es mit vergleichsweise einfachen Mitteln möglich, verschiedene Alternativen zu bestimmen. Die Beispiele haben gezeigt, dass wir hierbei bestimmte Zeichenfolgen vorgeben können oder die Auswahl auf bestimmte Symbole beschränken können. Auch präzise Angaben zur Anzahl der Zeichen sind möglich. Das erlaubt es, sehr präzise Vorgaben zu machen. Auf diese Weise erleichtern reguläre Ausdrücke die Analyse von Texten deutlich. Ohne diese Möglichkeit würde das eine sehr komplexe Aufgabe darstellen.
Bildquelle: https://commons.wikimedia.org/wiki/File:Email-regex.svg, CC 2.5, Pietrodn
Gute Zusammenfassung. Sollte es statt
Mit dem Ausdruck 1+1 können wir beispielsweise überprüfen, ob die Zeichenfolge „1+1“ in unserem Text vorhanden ist
nicht besser
Mit dem Ausdruck 1\+1 können wir beispielsweise überprüfen, ob die Zeichenfolge „1+1“ in unserem Text vorhanden ist
heißen?
Guten Tag,
vielen Dank für Ihren Kommentar!
Wir werden das überprüfen und falls notwendig korrigieren.
Über Hinweise/Verbesserungsvorschläge freuen wir uns immer!
Olena vom BMU Team