Um reguläre Ausdrücke – das Schweizer Taschenmesser für ITler – geht es in der einhundertsechzigsten Episode des IT-Berufe-Podcasts.
TL;DR
Ich arbeite fast täglich mit regulären Ausdrücken, um Texte nach Mustern zu durchsuchen und gefundene Inhalte zu verändern. Mit wenigen Grundbausteinen kannst du beispielsweise E-Mail-Adressen herausfiltern oder Vor- und Nachnamen vertauschen. Als IT-Azubi kannst du diese Kenntnisse in vielen Editoren und auf der Kommandozeile einsetzen. Für beliebige HTML- und XML-Dokumente brauchst du einen passenden Parser; bei Anwendungen mit hohen Anforderungen an die Laufzeit solltest du den Rechenaufwand regulärer Ausdrücke beachten.
Podcast: Play in new window | Download (Duration: 53:49 — 25.0MB)
Abonnieren: Apple Podcasts | Spotify | RSS
Kapitelmarken
- [00:00:01] Einstieg: Reguläre Ausdrücke im IT-Alltag
- [00:00:49] Was reguläre Ausdrücke leisten
- [00:03:04] Die Syntax verstehen und mit Websites ausprobieren
- [00:06:13] Muster beschreiben und Zeichen getrennt von ihrer Anzahl festlegen
- [00:09:35] Unterschiedliche Schreibweisen von Meier suchen
- [00:10:50] E-Mail-Adressen aus Dateien herausfiltern
- [00:12:03] Einsatz in Systemintegration und beim Bearbeiten von Listen
- [00:13:06] Wörtlich suchen und Sonderzeichen escapen
- [00:14:40] Erlaubte Zeichen und Grenzen des E-Mail-Beispiels
- [00:18:12] Zeichenbereiche mit eckigen Klammern bilden
- [00:20:30] Zeichenbereiche negieren
- [00:22:01] Zeilenanfang und Zeilenende erkennen
- [00:24:15] Der Punkt als Platzhalter
- [00:25:19] Quantifizierer und genaue Anzahlen
- [00:28:53] Ein vereinfachtes Suchmuster für E-Mail-Adressen
- [00:31:16] Alternativen mit der Pipe verbinden
- [00:33:03] Gruppen bilden und Inhalte beim Ersetzen wiederverwenden
- [00:36:40] Die wichtigsten Syntaxbausteine im Überblick
- [00:38:41] Praxisbeispiel: UUIDs herausfiltern
- [00:40:28] E-Mail-Adressen suchen und Namen vertauschen
- [00:41:33] Leerzeichen am Zeilenende entfernen
- [00:42:07] Markdown-Aufzählungszeichen einfügen
- [00:43:47] Felder für Klassen vorbereiten und im Blockmodus bearbeiten
- [00:45:54] Links zwischen HTML und Markdown umschreiben
- [00:47:29] Grenzen beim Verarbeiten von HTML und XML
- [00:49:17] Rechenaufwand und der Ausfall von Stack Overflow
- [00:50:37] Reguläre Ausdrücke in Shells, Editoren und IDEs
- [00:51:51] Literaturempfehlung und Websites zum Lernen
- [00:53:14] Feedback und Abschied
Inhalt
Ich schwärme immer mal wieder von regulären Ausdrücken. Das liegt wohl einfach daran, dass ich fast täglich mit ihnen arbeite. Sie sind einfach so unglaublich vielseitig verwendbar und machen ITlern das Leben leichter – wenn man sie beherrscht. Nicht umsonst gibt es diesen „Witz“:
Ich hatte ein Problem und versuchte es mit regulären Ausdrücken zu lösen. Nun habe ich zwei Probleme.
In den Händen eines erfahrenen Anwenders sind reguläre Ausdrücke allerdings äußerst hilfreich.
Sinn regulärer Ausdrücke
Reguläre Ausdrücke dienen der Mustererkennung in Zeichenketten und sind quasi Platzhalter on steroids. Statt der einfachen Platzhalter wie * oder ? z.B. in Dateinamen, gibt es viele verschiedene Platzhalter, Quantifizierer und weitere Regeln, um Muster in Texten zu definieren. Nach diesen Mustern kannst du suchen oder du kannst sie zum Ersetzen von Inhalten benutzen. Teilmuster lassen sich gruppieren und beim Ersetzen wiederverwenden. So gut wie jede Programmiersprache enthält eine eingebaute Unterstützung für reguläre Ausdrücke. Jeder vernünftige Texteditor unterstützt reguläre Ausdrücke beim Suchen und Ersetzen genauso wie eine gute Shell (z.B. Bash oder PowerShell).
Grundlegende Muster
- konkreten Zeichen(-folgen):
hallo - Bereiche:
[], z.B.[a-z],[0-9],[aeiou]- Negation mit
^, z.B.[^abc]
- Negation mit
- Zeilenanfang:
^(nicht mit der Negation verwechseln!) - Zeilenende:
$ - Platzhalter für ein beliebiges Zeichen:
. - Alternativen:
A|B - Quantifizierer (stehen hinter dem Muster)
- einmal oder keinmal (0..1):
? - keinmal, einmal oder mehrmals (0..n):
* - einmal oder mehrmals (1..n):
+ - genaue Anzahl:
{8},{2,5}(2 bis 5 mal)
- einmal oder keinmal (0..1):
- Gruppen:
(), Referenz mit$1 - Escapen von besonderen Zeichen (insb. alle obigen):
\
Anwendungsfälle aus meiner Praxis
Reguläre Ausdrücke gehören in den Werkzeugkasten jedes ITlers! Egal ob Anwendungsentwicklung oder Systemadministration, reguläre Ausdrücke können vielfältig eingesetzt werden. In der Linux-Administration können z.B. Black- und Whitelists für Hostnamen mit regulären Ausdrücken definiert werden. Die Apache-Konfiguration verwendet ebenfalls reguläre Ausdrücke. Auf der Linux-Kommandozeile kannst du mit grep in Dateien nach regulären Ausdrücken suchen. sed ermöglicht dir die Massenverarbeitung von Dateien. Das Suchen und Ersetzen im vi wird standardmäßig auch mit regulären Ausdrücken gemacht und du kannst sogar mit ihnen navigieren ($ springt z.B. zum Ende der Zeile).
- Suchen und Ersetzen in Dateien
- Listen umformatieren
- Nachname/Vorname zu Vorname/Nachname
- Anfang oder Ende von Zeilen manipulieren
- Markdown in HTML und umgekehrt
- Feldnamen mit
public String ;umschließen - Batchdatei generieren zum Verschieben von Dateien
- Whitespace trimmen
- UUIDs/Domains/Mails in Text/Logs finden
Konkrete Beispiele
Gerade vor wenigen Tagen hatte ich die – eigentlich triviale – Aufgabe, ein paar Dateien umzubenennen, die ein bestimmtes Präfix hatten. Dieses Präfix sollte ausgetauscht werden. Anstatt die Dateien per Hand umzubenennen (oder die entsprechende Shell-Funktion zu nutzen 😉 ), habe ich mir mit einem simplen regulären Ausdruck in wenigen Sekunden ein Shell-Script gebaut, das die Aufgabe für mich löst.
Basis war die Liste der Dateien, die ich in der PowerShell mit dir | ac liste.ps1 erstellt habe.
prefix-Datei1.txt
prefix-Datei2.txt
...
prefix-Datei100.txt
Mit dem Suchen-/Ersetzen-Muster /^(prefix-(.*))$/move $1 neuerPrefix-$2/g im Vim wurde daraus:
move prefix-Datei1.txt neuerPrefix-Datei1.txt
move prefix-Datei2.txt neuerPrefix-Datei2.txt
...
move prefix-Datei100.txt neuerPrefix-Datei100.txt
Die Datei konnte ich dann einfach mit .\liste.ps1 ausführen und war fertig!
- UUIDs suchen
- Text:
Text mit UUIDs wie z.B. 550e8400-e29b-11d4-a716-446655440000 mittendrin - RegEx:
[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12} - Suchergebnis:
550e8400-e29b-11d4-a716-446655440000
- Text:
- E-Mail-Adressen suchen
- Text:
Stefan Macke (mail@example.com) hat einen Podcast. - RegEx:
[a-z]+@[a-z]+\.[a-z]{2,3}(nicht ausreichend für echte Mails!) - Suchergebnis:
mail@example.com
- Text:
- Vor-/Nachnamen vertauschen
- Text:
Stefan Macke - RegEx:
(.+) (.+) - Ersetzen durch:
$2, $1 - Ergebnis:
Macke, Stefan
- Text:
- Trailing Whitespace entfernen
- Text:
Zeile mit Leerzeichen am Ende - RegEx:
+$ - Ersetzen durch: „
- Ergebnis:
Zeile mit Leerzeichen am Ende
- Text:
- Aus Zeilen Markdown-Aufzählungen machen
- Text:
Listenpunkt 1 - RegEx:
^ - Ersetzen durch:
*(Asterisk muss ggfs. escapet werden) - Ergebnis:
* Listenpunkt 1
- Text:
- Aus Namen Java-Attribute machen
- Text:
alterDerPersonInJahren - RegEx:
(.+) - Ersetzen durch:
private Integer $1; - Ergebnis:
private Integer alterDerPersonInJahren;
- Text:
- Aus HTML-Links Markdown machen
- Text:
<a href="https://it-berufe-podcast.de">IT-Berufe-Podcast</a> - RegEx:
<a href="([^"]+)">([^<]+)</a> - Ersetzen durch:
[$2]($1 "$2")(Klammern müssen ggfs. escapet werden) - Ergebnis:
[IT-Berufe-Podcast](https://it-berufe-podcast.de "IT-Berufe-Podcast")
- Text:
Grenzen regulärer Ausdrücke
Wofür du reguläre Ausdrücke nicht benutzen solltest:
- XML und HTML auseinandernehmen: Dafür brauchst du einen echten XML-Parser, da diese Sprachen zu „hoch“ für reguläre Ausdrücke sind.
- Performance-kritische Aktionen: Reguläre Ausdrücke sind teuer im Vergleich zu „normalem“ Suchen und Ersetzen, da sie geparst und in einen Zustandsautomaten übersetzt werden müssen. Ein suboptimaler regulärer Ausdruck hat sogar schon einmal StackOverflow zum Absturz gebracht.
Programme mit Unterstützung für reguläre Ausdrücke
- Kommandozeile:
grep(Bash),Select-String(PowerShell) - Editoren: Vim, Notepad++, Visual Studio Code
- IDEs: Eclipse, IntelliJ, Visual Studio
Und viele mehr…
Literaturempfehlungen
In diesem (zumindest für mich) spannenden Artikel zeigt Liz Bennett die – teils sehr deutlichen – Performance-Unterschiede zwischen guten und schlechten regulären Ausdrücken: Regexes: the Bad, the Better, and the Best.
In diesem tollen Artikel geht Nikita Popov auf die Hintergründe von regulären Ausdrücken ein und erklärt ganz nebenbei noch die Chomsky-Hierarchie und warum man HTML nicht mit regulären Ausdrücken parsen sollte: The true power of regular expressions. Ein wirklich spannender Artikel, der mir wieder mal zeigt, wie sinnvoll es ist, reguläre Ausdrücke zu beherrschen.
Eine witzige Möglichkeit, reguläre Ausdrücke zu lernen, ist übrigens das Regex Crossword. Damit habe ich auch schon einige Stunden verbracht! 😀
In Kapitel 10 (Konzepte der Programmierung) geht Sascha Kersken im IT-Handbuch für Fachinformatiker* auf reguläre Ausdrücke ein und zeigt Programmierbeispiele in Java und Python.
Links
Zusammenfassung
Muster in Texten finden
Ich setze reguläre Ausdrücke fast täglich ein, etwa wenn ich aus großen Dateien bestimmte Angaben herausfiltern möchte. Du beschreibst damit, wie ein gesuchter Text aufgebaut ist, und kannst anschließend die passenden Stellen bearbeiten. Dabei legst du fest, welche Zeichen vorkommen dürfen und wie oft sie erscheinen sollen.
Ein Beispiel sind unterschiedliche Schreibweisen des Nachnamens Meier. Ein Suchmuster kann mehrere Varianten erfassen. Auch E-Mail-Adressen lassen sich anhand ihres Aufbaus in einer Datei finden, obwohl dir die konkreten Adressen vorher unbekannt sind.
Für dich als IT-Azubi gehört das Thema sowohl zur Anwendungsentwicklung als auch zur Systemintegration. Systemadministrator:innen bearbeiten beispielsweise Listen mit Benutzernamen oder filtern Angaben aus Dateien.
Die Grundbausteine verstehen
- Wörtlicher Text:
Hallosucht genau diese Zeichenfolge. - Escaping: Hat ein Zeichen eine besondere Bedeutung, setzt du für die wörtliche Suche einen Backslash davor. Mit
\.suchst du einen Punkt. Das@kannst du direkt schreiben. - Zeichenbereiche: Eckige Klammern legen fest, welches Zeichen an einer Stelle stehen darf.
[a-z]steht für einen Kleinbuchstaben,[0-9]für eine Ziffer. Mehrere Bereiche kannst du innerhalb derselben Klammern verbinden. Einzelne Zeichen lassen sich ebenfalls aufführen, etwa die Vokale in[AEIOU]. - Bereiche ausschließen: Ein
^direkt am Anfang einer Zeichenklasse schließt die folgenden Zeichen aus.[^AEIOU]erfasst jedes Zeichen außerhalb dieser Auswahl. Dazu gehören auch Sonderzeichen. - Zeilenanfang und Zeilenende: Im beschriebenen Einsatz steht
^für den Zeilenanfang und$für das Zeilenende. So findest du beispielsweise mit^#Zeilen, die mit einer Raute beginnen, etwa auskommentierte Einstellungen in einer Linux-Konfigurationsdatei. - Beliebiges Zeichen: Der Punkt
.steht für ein einzelnes beliebiges Zeichen. - Alternativen: Eine Pipe
|verbindet mögliche Suchmuster. MitA|Bsuchst du nach A oder B. Auf diese Weise kannst du auch bekannte Schreibweisen eines Namens aufführen.
Die Bedeutung eines Zeichens hängt von seiner Position ab. Das ^ am Anfang einer Zeichenklasse schließt Zeichen aus; außerhalb dieses Bereichs dient es als Anker für den Zeilenanfang.
Festlegen, wie oft ein Muster vorkommt
Quantifizierer stehen hinter dem Zeichen oder Muster, auf das sie sich beziehen:
| Zeichen | Bedeutung |
| — | — |
| ? | Nullmal oder einmal |
| * | Nullmal oder beliebig oft |
| + | Mindestens einmal |
| {8} | Genau achtmal |
| {2,5} | Mindestens zweimal, höchstens fünfmal |
Mit .* beschreibst du beliebig viele beliebige Zeichen. .+ verlangt mindestens ein Zeichen.
Das vereinfachte E-Mail-Beispiel lautet [a-z0-9]+@[a-z]+\.[a-z]{2,3}. Vor dem @ stehen dabei mindestens ein Kleinbuchstabe oder eine Ziffer, dahinter mindestens ein Kleinbuchstabe. Nach dem wörtlichen Punkt folgen zwei bis drei Kleinbuchstaben.
Dieses Beispiel deckt eine begrenzte Auswahl ab. Echte E-Mail-Adressen erlauben weitere Zeichen, und Top-Level-Domains können länger sein. Beim Schreiben eines Suchmusters musst du deshalb wissen, welche Varianten deine Datei enthält. Auch Großbuchstaben musst du berücksichtigen, wenn sie im Text vorkommen.
Auf Teile eines Treffers zugreifen
Runde Klammern bilden Gruppen, deren Inhalte du später wiederverwenden kannst. Bei einer E-Mail-Adresse lässt sich beispielsweise die Domain als Gruppe erfassen und separat ausgeben.
Beim Ersetzen greifst du über Gruppenreferenzen auf diese Inhalte zu. Je nach Editor heißen sie \1 und \2 oder $1 und $2. Für eine einfache Liste mit jeweils einem Vor- und Nachnamen sucht (.+) (.+) beide Teile als Gruppen. Durch Ersetzen mit $2, $1 entsteht das Format "Nachname, Vorname". Das Beispiel setzt Namen ohne zusätzliche Bestandteile voraus.
Beispiele aus meinem Alltag
- UUIDs herausfiltern: In einer großen Textdatei habe ich UUIDs anhand ihrer Hexadezimalzeichen und Bindestriche gefunden. Die Blöcke enthielten 8, 4, 4, 4 und 12 Zeichen. Dafür beschreibst du die erlaubten Zeichen von A bis F sowie 0 bis 9 und ergänzt die jeweilige Anzahl in geschweiften Klammern.
- Leerzeichen am Zeilenende entfernen: Das Muster
+$findet ein oder mehrere Leerzeichen unmittelbar vor dem Zeilenende. Wenn du den Treffer durch einen leeren Text ersetzt, verschwinden diese Leerzeichen. - Aufzählungszeichen einfügen: Du suchst nach
^und ersetzt den Zeilenanfang durch*, um Zeilen als Markdown-Liste zu schreiben. Ob du das Sternchen im Ersatztext escapen musst, hängt vom Editor ab. - Felder für eine Klasse vorbereiten: Mit
(.+)erfasst du den Inhalt einer Zeile. Der Ersatztextprivate Integer $1;ergänzt den Text davor und das Semikolon dahinter. Als weitere Möglichkeit erwähne ich den Blockmodus einer IDE, mit dem du mehrere Zeilen gleichzeitig bearbeiten kannst. - Links umschreiben: Bei einfachen HTML-Links erfasse ich die URL und den Linktext in getrennten Gruppen. Diese setze ich anschließend an den passenden Stellen der Markdown-Syntax ein. Ähnliche Schritte sind bei anderen Textformaten möglich.
Grenzen beachten
Für meine einfachen Links arbeite ich mit einer Textdatei, deren Inhalt ich kenne und kontrolliere. Sobald ein Programm beliebige HTML- oder XML-Dokumente verarbeiten soll, brauchst du einen entsprechenden Parser. Verschachtelte Tags und ihre passenden schließenden Tags erfordern mehr als die beschriebenen regulären Suchmuster. Als theoretischen Hintergrund nenne ich die Chomsky-Hierarchie.
Auch der Rechenaufwand spielt eine Rolle. Reguläre Ausdrücke werden intern in einen Zustandsautomaten überführt und können viel Rechenzeit beanspruchen. Wenn es in deiner Anwendung auf Millisekunden ankommt, solltest du einfache String-Funktionen als mögliche Lösung prüfen. Ein verlinkter Bericht über einen Ausfall von Stack Overflow zeigt, wie ein aufwendiger regulärer Ausdruck den Betrieb einer Website beeinträchtigen kann.
In deinen Werkzeugen ausprobieren
Auf der Kommandozeile kannst du mit grep nach regulären Ausdrücken suchen. PowerShell bietet dafür Select-String.
Bei den Editoren nenne ich unter anderem Notepad++ und Visual Studio Code, außerdem vi und Emacs. Auch IDEs wie Eclipse und IntelliJ unterstützen reguläre Ausdrücke; weitere Beispiele sind Visual Studio und PhpStorm. Die Grundbausteine kannst du in verschiedenen Werkzeugen anwenden, wobei sich insbesondere die Syntax beim Ersetzen unterscheiden kann.
Zum Lernen empfehle ich dir, eigene Muster mit Beispieltexten auszuprobieren. Websites wie regextester.com erläutern die einzelnen Zeichen eines Ausdrucks und zeigen dir, welche Textstellen passen. Meine Beispiele und weitere Links stehen in den Shownotes zur Episode 160 auf der Podcast-Website.
Im IT-Handbuch für Fachinformatiker von Sascha Kersken findest du ebenfalls einen Einstieg. In der zum Zeitpunkt der Aufnahme aktuellen Ausgabe behandelt Kapitel 10 reguläre Ausdrücke anhand von Java und Python.
Transkription der gesamten Episode
Automatisch erzeugte Transkription der Episode
Herzlich willkommen zum IT-Berufe-Podcast, dem Podcast rund um die Ausbildung in den IT-Berufen.
In dieser Episode geht es um ein Schweizer Taschenmesser für ITler, und zwar reguläre Ausdrücke. Viel Spaß!
Hallo und herzlich willkommen zur 160. Episode des IT-Berufe-Podcasts.
Mein Name ist Stefan Macke und heute geht es mal um ein Thema, was mir persönlich sehr am Herzen liegt,
weil ich diese Technologie fast täglich anwende in meinem Alltag, würde ich sagen.
Es gibt immer mal wieder einen Einsatzzweck dafür.
Und ich habe noch nie so richtig darüber gesprochen, immer so nebenbei, zum Beispiel mit Buchclubs und so weiter.
Aber heute möchte ich dem Thema mal eine eigene Episode widmen, und zwar reguläre Ausdrücke.
Wer das noch nie gehört hat, da geht es darum, dass wir quasi Muster in Texten definieren können und finden können,
und dann auch zum Suchen und Ersetzen benutzen können.
Das erst mal so ganz grob gesagt.
Wenn du es vergleichst vielleicht, wenn du auf der Kommandozeile irgendwo dir Dateien anzeigen möchtest,
mit dir zum Beispiel unter Windows oder mit ls auf Linux, da kannst du so Platzhalter angeben,
wie zum Beispiel Sternchen, und dann sowas schreiben wie Sternchen.jpg,
und dann zeigt er dir alle Dateien an, die jpg heißen hinten, egal welcher Dateiname davor steht.
Dafür steht halt das Sternchen als Platzhalter für beliebig viele Zeichen.
Und die regulären Ausdrücke können jetzt noch ein bisschen mehr als das.
Nicht einfach nur beliebig viele Zeichen oder ein Zeichen, zum Beispiel das Fragezeichen bei diesen Dateinamen,
sondern ganz, ganz, ganz viel mehr.
Und damit kann man sehr komplexe Konstrukte bilden, um dann aus Texten bestimmte Informationen rauszuextrahieren
und dann auch zu transformieren, eben Suchen und Ersetzen vor allem.
Dafür benutze ich es ganz häufig.
Und auf den ersten Blick könnte man jetzt meinen, ja mein Gott, wann brauche ich sowas, ja?
Aber ich habe extra ein paar Beispiele mitgebracht aus meinem Alltag, um zu zeigen, dass ich das wirklich,
also fast täglich brauche ich irgendwo reguläre Ausdrücke oder brauchen.
Ich wende sie einfach an, weil ich nichts Besseres habe, das ist jetzt auch blöd gesagt,
aber nichts Schnelleres habe oder nichts Einfacheres, darum geht es einfach.
Denn wenn man die regulären Ausdrücke beherrscht, kann man damit sehr schnell sehr viele coole Dinge tun.
Und wenn man sie nicht beherrscht, ja, dann muss man sich halt irgendwelche anderen Sachen suchen.
Und deswegen möchte ich heute einfach mal ein bisschen drüber erzählen.
Ich weiß, dass das Thema jetzt auch für eine Podcast-Episode ein bisschen schwierig ist,
denn reguläre Ausdrücke sind ja ein bisschen wie eine Programmiersprache.
Man muss ja auch die Zeichen lernen und verstehen.
Und das Ganze jetzt nur auf der Audiospur wiederzugeben, wird wahrscheinlich ein bisschen schwierig.
Aber ich versuche mein Bestes und ich würde dir auf jeden Fall empfehlen,
im Nachgang dir mal die Syntax genau anzugucken.
Am besten mit so einer Website, die ich auch in den Shownotes habe, einfach mal auszuprobieren.
Und dann am besten im Alltag auch mal anzuwenden.
Und ich habe auch noch eine Literaturempfehlung am Ende, wo du es wirklich nachlesen kannst,
wo das dann ganz genau eingeführt wird und beschrieben wird.
Ich möchte jetzt heute die Chance hier nutzen, um einfach mal, ja,
kundzutun, wie toll ich diese Möglichkeit finde, in Texten zu suchen und zu ersetzen
und was man damit halt so anstellen kann.
Und ich hoffe, dass das so ein bisschen rüberkommt und dass du dann motiviert wirst, dir das mal im Detail anzugucken.
Jetzt habe ich gerade schon gesagt, das könnte auf der Audiospur ein bisschen schwierig werden,
reguläre Ausdrücke vernünftig zu vermitteln.
Viele sagen, dass das auch schwierig ist, wenn man sie sehen kann.
Denn wenn man sich so fertige, reguläre Ausdrücke mal anguckt, dann sehen die schon ziemlich kryptisch aus.
Die bestehen nämlich aus ganz vielen Sonderzeichen und jedes Sonderzeichen hat eine besondere Bedeutung.
Und wenn man die jetzt einfach hintereinander liest, wird man nicht auf die Idee kommen,
dass da irgendwelche Muster in Texten mit gemeint sind,
sondern es sieht einfach aus wie, ja, Kraut und Rüben in Anführungszeichen.
Es ist also nicht schön lesbar wie so eine Programmiersprache oder sowas,
sondern es sind wirklich ein ganzer Haufen an Sonderzeichen, die irgendwie scheinbar wahllos zusammengewuschelt sind.
Und deswegen gibt es auch so einen kleinen Witz in der IT.
Ich hatte ein Problem und versuchte es mit regulären Ausdrücken zu lösen.
Jetzt habe ich zwei Probleme.
Einfach, um zu zeigen, dass es wirklich ziemlich kompliziert ist.
Wobei es ist eigentlich nur auf den ersten Blick kompliziert.
Denn wenn man die Zeichen verstanden hat, ist es relativ einfach, solche regulären Ausdrücke auseinanderzunehmen.
Und selbst wenn man sie nicht verstanden hat, gibt es Websites wie die oneonone,
z.B. regextester.com.
Die habe ich auch in den Shownotes natürlich verlinkt zu dieser Episode.
Übrigens findest du die wie immer unter itberufe-podcast.de-160 für die heutige 160. Episode.
Und da kann man die einfach eingeben.
Da werden die wirklich Zeichen für Zeichen auseinandergenommen mit Erklärungen daneben,
was das heißt und was dieses Zeichen in diesem Kontext heißt und so weiter.
Also es gibt da schon super Tools, die einem diese regulären Ausdrücke erklären.
So ist es jetzt auch nicht.
Aber wenn man wirklich gar keine Ahnung davon hat, dann sieht es schon etwas wild aus, sage ich mal.
Und dann kann man vielleicht verstehen, wenn der eine oder andere sagt,
oh Gott, geh mir mit den regulären Ausdrücken weg, das habe ich noch nie verstanden.
Oder, oh, die sind so kompliziert und so.
Also ich finde, sind sie gar nicht.
Es gibt so ein paar wichtige Grundbestandteile, die man häufig mal braucht
und die man auch im Alltag sehr häufig einsetzen kann.
Man muss jetzt nicht die absolut wildesten Kombinationen, die man so gut wie nie benötigt, auch noch können.
Von daher, wenn man ein paar Grundbausteine verstanden hat,
dann kann man, glaube ich, sehr einfach auch reguläre Ausdrücke verstehen.
Natürlich, wenn sie lang sind, ist es genau wie bei Programmen, wie ich programmiert habe.
Wenn lange Programme, muss ich auch ein bisschen Zeit investieren, um die zu verstehen.
Bei regulären Ausdrücken das Gleiche.
Aber ich würde heute auf jeden Fall mal so die wichtigsten Muster oder Bestandteile
von solcher regulären Ausdrücke mal einmal durchgehen.
Dann hast du die wenigstens schon mal gehört.
Und dann würde ich halt dringend empfehlen, die nochmal nachzulesen.
Wie gesagt, Literaturempfehlung, dazu habe ich auch.
Und nachdem wir uns das angeguckt haben, wie die grundsätzlich funktionieren,
habe ich dann ein paar konkrete Anwendungsfälle aus meiner Praxis mitgebracht,
um dir zu zeigen, wofür man sowas eigentlich einsetzen kann.
Woran man vielleicht sonst gar nicht so denkt, dass man das damit lösen könnte.
Dann noch ein kurzer Ausblick, wo du vielleicht reguläre Ausdrücke nicht für benutzen solltest.
Denn es ist, in der Einleitung habe ich schon gesagt, es ist ja das Schweizer Taschenmesser für IT-ler.
Aber das heißt nicht, dass es ein goldener Hammer ist,
mit dem du auf alles draufkloppen musst.
Also du kennst vielleicht das Sprichwort, wenn du nur einen Hammer hast, sieht alles aus wie ein Nagel.
So ist es bei regulären Ausdrücken nicht.
Du kannst nicht alles damit lösen.
Und es gibt gewisse Grenzen, die solltest du einfach kennen,
um zu wissen, wofür du dieses Werkzeug sinnvollerweise einsetzen kannst.
Zum Schluss, wie gesagt, noch ein paar Literaturempfehlungen, dann sind wir auch schon durch.
Und den Rest musst du dann sowieso anlesen oder ausprobieren auf den Websites, wie gesagt.
Von daher würde ich sagen, wir steigen einfach mal ein mit dem Aufbau von regulären Ausdrücken.
Das heißt mit der grundsätzlichen Idee noch mal einmal kurz erklärt.
Ich hatte das Beispiel mit diesen Dateinamen schon genannt.
Und das kennst du vermutlich von deiner Kommandozeile.
Das häufigste Beispiel für so einen Platzhalter in beliebigen Texten ist eben das Sternchen.
Oder auf Englisch der Begriff Asterisk.
Das ist das Ding, was du eingibst mit Shift und dem Pluszeichen neben deinem Enter.
Dieses kleine Sternchen auch als Malzeichen benutzt.
Und das wird in ganz vielen Sprachen oder Tools oder Editoren, wie gesagt, als Platzhalter benutzt für irgendein Zeichen beliebig oft.
Das heißt, wie gesagt, wenn du sowas eingibst wie dir, Sternchen.jpg, dann kann anstelle des Sternchens irgendwas stehen.
Da könnte ABC stehen oder Hallo oder ich weiß nicht was.
Und dann wird halt alles gesucht, was eben diesem Muster entspricht.
Und jetzt sind die regulären Ausdrücke sehr, sehr ähnlich aufgebaut.
Das heißt, es gibt Zeichen, die Platzhalter für andere sind.
Es gibt aber auch so Zeichenbereiche, wo ich sagen kann, an dieser Stelle hätte ich gerne ein Zeichen, aber zum Beispiel nur die Buchstaben von A bis F, meinetwegen.
Wenn ich zum Beispiel Hexadezimalzahlen suche oder sowas.
Und dann kann ich aber auch etwas feingliederiger als nur mit diesem Sternchen zum Beispiel sagen, wie oft bestimmte Zeichen auftauchen sollen.
Das wird hier ein bisschen getrennt.
Das ist also nicht hier wie bei dem Sternchen ein beliebiges Zeichen beliebig oft, sondern das wird halt einmal aufgeteilt.
Beliebiges Zeichen und ein zweites Zeichen steht dann für beliebig oft zum Beispiel.
Also die regulären Ausdrücke können mehr als dieser simple Platzhalter Sternchen, sind dann aber logischerweise auch ein bisschen komplizierter.
Einfach weil du mehr Zeichen brauchst, um das gleich auszudrücken, weil du einfach mehr ausdrücken kannst.
Das heißt also, das Tool ist sehr mächtig, das kann sehr viel, aber du musst es halt eben auch beherrschen und den Sinn der einzelnen Zeichen verstehen,
um genau das formulieren zu können, was du auch wirklich ausdrücken möchtest.
So und jetzt ist dieser grundsätzliche Sinn hinter den regulären Ausdrücken, also ein Muster in Texten zu erkennen.
Jetzt kann man sich fragen, ja gut, wofür braucht man das?
Nehmen wir nochmal dieses Beispiel mit dem Sternchen auf der Kommandozeile.
Also wenn du ein Verzeichnis hast, in dem ein paar hundert Dateien liegen und meinetwegen JPEG-Dateien und Excel-Dateien und DOC-Dateien oder wie auch immer,
und du möchtest nur die JPEG-Dateien löschen, dann wird es relativ frickelig, die 57 Dateien, die JPEG heißen, einzeln rauszusuchen und einzeln zu löschen.
Also auf der Kommandozeile sowas wie rm auf Linux oder del auf Windows, ja, und dann jede einzelne Datei anzugeben, da wirst du ja verrückt.
Da musst du 57 mal del JPEG-1, del JPEG-2 eingeben und so weiter.
Das heißt, hier wäre ein Platzhalter ganz sinnvoll, wo du dann was sagst, del Sternchenpunkt JPEG,
und dann werden einfach alle JPEG-Dateien gelöscht, egal wie sie heißen vor der Dateiendung.
Und genau darum geht es eigentlich auch bei regulären Ausdrücken.
Wenn du in Texten irgendetwas suchen willst, dann kannst du halt eine wörtliche Suche machen,
das kann eigentlich jeder Texteditor, sogar der dumme Notepad in Windows kann das, ja,
also STRG-F, suchen, und dann gibst du halt einen Text ein und dann findet er exakt diesen Text in deinem Text.
Ja, logisch, wenn er nicht da ist, findet er halt auch nichts.
So, aber problematisch wird es halt, wenn der Text, den du suchst, eben nicht exakt definiert ist,
sondern sich vielleicht ein bisschen unterscheiden kann, oder wenn du eben genau nach solchen Mustern suchen willst
und du vielleicht nicht genau weißt, wie es aufgebaut ist, oder du weißt, wie es aufgebaut ist,
aber eben nicht genau, wie die Werte sind.
Nehmen wir mal ein simples Beispiel, du suchst zum Beispiel den Herrn Meier in deinem Text.
Und jetzt kann Meier, der deutsche Nachname, ja ziemlich unterschiedlich geschrieben sein,
mit A, I, mit E, Y, mit, ich weiß nicht was, sogar M, A, Y, R habe ich schon mal gesehen.
Ja, also es gibt die wildesten Schreibweisen.
Und wenn du jetzt nur von deinem, keine Ahnung, Mitarbeiter gehört hast, such mal den Herrn Meier,
und du hast aber keine Ahnung, wie der geschrieben wird, ja, wonach willst du denn jetzt suchen?
Dann müsstest du jetzt jede einzelne Kombination von Meier, die dir einfällt, im Text suchen
und hoffen, dass es die da gibt, ja?
Und wenn du jetzt einfach sagst, Mensch, Meier, okay, das fängt mit einem großen M an
und hört mit einem R auf und dazwischen kann stehen ein A, ein Y, ein E, ein I,
dann hast du quasi schon ein Muster, nach dem du dort suchen kannst.
Also anstatt einfach exakt nach M, E, I, E, R zu suchen, für die Standardschreibweise von Meier,
jedenfalls in meiner Welt, ja, könntest du einfach sagen, such mir doch mal einen Text,
der mit einem großen M anfängt, mit einem kleinen R aufhört
und wo dazwischen irgendwo A, Y, E oder I zusammengewürfelt stehen.
Und dann hättest du auf einen Schlag alle möglichen Schreibweisen von Meier in deinem Text gesucht
und müsstest nicht alle per Hand eingeben.
Das heißt, du hast wirklich schon mal eine kleine Arbeitserleichterung, eine Zeitersparnis,
weil du halt nicht alles, alle Kombinationsmöglichkeiten quasi händisch durchprobieren musst, ja?
Oder ein anderes Beispiel, du sollst irgendwie, keine Ahnung, aus einem E-Mail-Protokoll
alle E-Mail-Adressen, die da benutzt wurden, raussuchen.
Das ist tatsächlich sogar ein echter Angangsfall, den ich schon mal hatte, ja?
Mir ein Kollege aus dem Vertrieb so eine Riesendatei gegeben, da waren irgendwo E-Mail-Adressen drin
und die sollte ich alle raussuchen, damit er die dann anschreiben konnte.
So, und jetzt die Frage, wie machst du das?
Du hast keine Ahnung, welche E-Mail-Adressen drinstehen, wie die heißen, wie die Domains sind,
du weißt nichts, ja?
Und jetzt könntest du hergehen und händisch die ganze Datei durchscrollen, ja, könntest du machen.
Oder du baust dir halt ein Muster und sagst, ich suche bitte nach Zeichenketten,
die wie folgt aufgebaut sind.
Irgendwelche Zeichen beliebig oft, dann kommt ein At-Zeichen,
dann kommen nochmal irgendwelche Zeichen beliebig oft,
dann kommt ein Punkt und dann kommen meinetwegen zwei bis drei Buchstaben.
Das ist dann die Top-Level-Domain, ja?
Und mit diesem Muster kannst du jetzt den ganzen Text durchsuchen
und dann findet er alle E-Mail-Adressen.
Natürlich nur, wenn die so aufgebaut sind.
Es gibt ja auch noch lokale E-Mail-Adressen, die gar keine Domain haben und so weiter.
Das nehmen wir jetzt mal alles raus, sind Ausnahmen, ja?
Aber die normalen E-Mail-Adressen, die man so draußen kennt
und von Geschäftspartnern wahrscheinlich bekommt,
sehen halt irgendwie so aus.
Zeichen, At, Zeichen, Punkt, Zeichen, ja?
Und wenn du dieses Muster dann benutzt, um danach zu suchen,
dann findest du auf einen Schlag alle E-Mail-Adressen
und kannst die rausfiltern, was auch immer du damit tun willst.
Also, das nochmal zum grundsätzlichen Sinn,
warum wir als ITler diese Dinge eigentlich kennen sollten.
Und das hat auch nichts mit Programmierung zu tun.
Im Gegenteil, das ist für mich, für alle IT-Berufe interessant.
Insbesondere auch für Systemadministratoren, ne?
Fachinformatiker, Systemmitigation.
Denn die haben ganz häufig solche Aufgaben wie Massenverarbeitung von irgendwelchen Dingen,
die halt nicht eins zu eins bekannt sind,
sondern irgendwelchen Mustern entsprechen, ne?
Ich weiß es nicht. Benutzernamen aus dem Active Directory
sind vielleicht einfach Kleinbuchstaben von 1 bis 8 der Länge, ja?
Sowas, zum Beispiel. Oder eben E-Mail-Adressen.
Oder, ich weiß nicht was, irgendeine Liste,
die da auseinandergenommen werden soll, ne?
Mitarbeiternamen sollen auseinandergenommen werden
und Nachname, Vorname auseinandergenommen werden, wie auch immer, ja?
Also alles, wo ich Texte verarbeite,
was mich irgendwie per Hand länger als 10 Sekunden kosten würde,
da würde ich überlegen, ob ein regulärer Ausdruck vielleicht sinnvoll ist, ne?
Also so eine Art, ja, Listen- oder Massenverarbeitung.
Und jetzt gucken wir uns nochmal an,
wie jetzt also reguläre Ausdrücke aufgebaut sind,
welche Bestandteile haben wir da als Möglichkeit,
um dort Muster zu definieren.
Ganz einfach zum Einstieg.
Ich kann wörtlich einfach Text eingeben oder Zeichen eingeben
und dann werde ich einfach danach suchen.
Das heißt, wenn ich einfach Hallo eingebe,
dann findet der reguläre Ausdruck Hallo,
genauso wie wenn ich eine wörtliche Suche gemacht hätte, ja?
Also wenn ich wirklich Zeichen eingebe,
sucht der reguläre Ausdruck mir exakt dieses Zeichen,
genauso wie man es eigentlich auch gewohnt ist.
Außer dieses Zeichen hat eine besondere Bedeutung.
Denn dann müssten wir dafür sorgen,
dass dieses besondere Zeichen
als ganz normales Zeichen interpretiert wird.
Und du weißt schon, wie das geht vielleicht aus der Programmierung,
nämlich mit dem Escaping.
Das heißt, anstatt, ich nehme jetzt mal das Beispiel Punkt,
werde ich gleich noch erklären, was der Punkt bedeutet,
aber der Punkt hat eine besondere Bedeutung in einem regulären Ausdruck.
Das heißt, wenn ich zum Beispiel, wie eben,
nach einer E-Mail-Adresse suche, wo ein Punkt drin steht,
um die Top-Level-Domäne abzutrennen,
dann muss ich vor dem Punkt einen Backslash schreiben,
um diesen Punkt zu escapen.
Das heißt, der Punkt hat in einem regulären Ausdruck
eine besondere Bedeutung.
Die möchte ich aber nicht suchen,
sondern ich möchte wirklich den Punkt als Zeichen suchen.
Deswegen schreibe ich den Backslash davor.
Und so kann ich also, wenn ich simpel
nach exakt definiertem Text suchen will,
einfach diese Zeichen eingeben,
muss nur darauf achten, diese besonderen Zeichen zu escapen.
Also, das Beispiel der E-Mail würde dann irgendwie so aussehen,
Zeichen, Add, Zeichen, Backslash, Punkt, irgendwelche Zeichen,
weil der Punkt eben eine besondere Bedeutung hat.
Das Add-Zeichen hat zum Beispiel keine besondere Bedeutung,
ist zwar ein Sonderzeichen, aber nicht für reguläre Ausdrücke,
deswegen kann ich das einfach 1 zu 1 so hinschreiben.
Also, bis jetzt haben wir noch nichts gewonnen.
Aber wenn wir mal zurückgehen zu dem Beispiel der E-Mail,
wenn ich irgendwelche E-Mail-Adressen suche
und ich hatte eben gesagt, ich suche irgendwelche Zeichen,
Add-Zeichen und so weiter,
was ist denn mit diesen Zeichen gemeint?
Da kann ich jetzt nicht ABC eingeben oder irgendwas,
weil ich weiß ja nicht, was vor dem Add steht.
Das heißt, hier müsste ich jetzt wirklich mal
zum ersten Mal ein echtes Muster benutzen.
Und ich könnte ein Muster benutzen wie
Buchstaben von A bis Z.
Ja, das wäre vielleicht ein Muster.
Oder Ziffern von 0 bis 9.
Oder Großbuchstaben von A bis Z. Oder, oder.
Das heißt, ich könnte eine Art Bereich
von erlaubten Zeichen eingeben.
Und das könnte ich jetzt bei der E-Mail-Adresse auch tun.
Da könnte ich sagen, vor dem Add-Zeichen
dürfen Kleinbuchstaben, Großbuchstaben,
Ziffern stehen.
Und die könnte ich dann als sogenannten Zeichenbereich
angeben. Und dann sage ich einfach
irgendein Buchstabe oder Ziffer,
dann kommt das Add-Zeichen,
nochmal irgendwelche Buchstaben und Ziffern,
dann kommt der Escapede-Punkt und dann
nochmal irgendwie nur Buchstaben,
weil Top-Level-Domains mit Ziffern
kenne ich nicht. Ich glaube, die gibt es nicht.
Das heißt, wir müssen auch, wenn wir danach suchen,
genau wissen, was für Zeichen an der Stelle erlaubt sind.
Das ist schon mal wichtig zu wissen.
Wenn ich irgendwie Zeichen angebe,
die in der Realität da gar nicht vorkommen,
findet der reguläre Ausdruck natürlich auch nichts.
Also ich muss schon ziemlich genau wissen,
was zum Beispiel in E-Mail-Adressen denn
vor dem Add-Zeichen stehen darf.
Und da darf natürlich noch mehr stehen als nur Ziffern und Buchstaben.
Das ist klar. Übrigens, Groß- und Kleinbuchstaben
werden gar nicht unterschieden. Das heißt, ich könnte nur
nach Kleinbuchstaben suchen. Wenn allerdings
in meinem Text jemand auf die Idee kommt,
die E-Mail-Adresse mit Großbuchstaben zu schreiben,
was okay ist, was nur keinen Unterschied macht,
dann findet der reguläre Ausdruck das nicht.
Also wenn ich meine E-Mail-Adresse
steffan.macke.altreumauer.de zum Beispiel
hinschreibe und ich mache das S und das M
von meinen Anfangsbuchstaben groß,
dann findet der reguläre Ausdruck das nicht, wenn ich sage,
da dürfen nur Kleinbuchstaben stehen. Logisch.
Also ich muss einmal wissen, was ist denn da erlaubt,
aber auch, was ist denn in meinem konkreten Text,
den ich analysieren will, tatsächlich gegeben.
Und wenn jetzt meine Kollegen
zum Beispiel, die vielleicht von IT
noch nicht so viel Ahnung haben,
einfach immer mit Großbuchstaben
schreiben, auch in ihrer E-Mail-Adresse,
ja gut, da muss ich darauf halt eingehen, da muss ich halt
sagen, okay, vor dem Ad dürfen wohl auch
Großbuchstaben stehen. Also
ich nehme jetzt ein ganz simplifiziertes
Beispiel, was vor dem Ad-Zeichen stehen
darf. Übrigens E-Mail-Adressen
ist ein Beispiel für, ich glaube, einen der
längsten regulären Ausdrücke, die ich jemals
gesehen habe, einfach weil da so viele
Kombinationsmöglichkeiten
erlaubt sind. Das kannst du dir vielleicht gar nicht
vorstellen, weil du nur die üblichen E-Mail-Adressen aus deinem
Alltag kennst. Aber was da
technisch erlaubt ist, ja, es gibt
E-Mail-Adressen ohne Domain-Namen.
Es gibt E-Mail-Adressen, ich glaube,
sogar ohne Top-Level-Domain, ich glaube, sogar ohne
Ad-Zeichen und so weiter. Also da gibt es ganz,
ganz viele Sachen. Du kannst dir mal das RFC dazu
angucken, den Request for Comments
zum Beschreiben
von E-Mail-Adressen. Das ist
wirklich enorm, was es da alles gibt.
Das heißt, wenn du das Ding mal eben
eingeben willst, das wird nicht funktionieren. Das ist
mehrere Zeilen lang, der reguläre
Ausdruck, um beliebige E-Mail-Adressen
auseinanderzunehmen. Von daher, darauf
ziele ich jetzt mal nicht ab, sondern ich nehme wirklich ein ganz einfaches
Beispiel, sowas wie Name
Ad-Domain Punkt Top-Level-Domain.
Und um das zu suchen,
da dürfte halt vielleicht vor dem Ad-Zeichen
eben sowas stehen wie kleinen Buchstaben
und Ziffern, aber auch in der Realität
weißt du ja schon, da gibt es noch mehr. Da dürftest du auch
ein Minuszeichen hinschreiben oder einen Punkt
oder ich weiß nicht was.
Von daher, es kann beliebig komplex werden.
Wir gehen mal davon aus, dass wir da eben nur
Ziffern und Buchstaben vielleicht haben. Das heißt,
ich könnte sowas sagen, vor dem Ad-Zeichen
dürfen eben alle Ziffern von 0 bis
9 und alle Buchstaben von A bis Z
zum Beispiel stehen. Und wie gebe ich das
jetzt ein in einem regulären Ausdruck?
Ja, dafür gibt es solche Zeichenbereiche
und die werden in eckigen Klammern
umschlossen. Ich hoffe, du kennst
noch aus irgendeiner anderen Episode von mir
die ganzen verschiedenen Klammern, die es so gibt in der Informatik.
Es gibt die runden Klammern,
die kennst du auch aus dem Deutschunterricht wahrscheinlich,
wenn man irgendwie einen Einschub im Text hat oder sowas.
Die ganz normalen mit Shift-8
und Shift-9. Dann gibt es die
eckigen Klammern und das sind die, die ich jetzt hier meine.
Das ist auf der Tastatur das Alt-Grrr
mit 8 und 9.
Und ja, die sehen halt
aus, auf Englisch heißen sie
Brackets, und die sehen aus
wie so Klammern, die du
mit dem Locher,
nicht mit dem Locher, mit dem Tacker
in DIN A4-Papier zum Beispiel rein
tackerst, wenn du irgendwie einen Beleg dran heften willst
oder so. Also das sind die
eckigen Klammern. Dann haben wir noch die
spitzen Klammern, auf Englisch auch
Angle Brackets, für Winkel.
Das heißt, ja, das ist größer
und kleiner Zeichen im Prinzip auf deiner Tastatur.
Und dann gibt es noch die geschwungenen
Klammern, das sind die, die wir als Programmierer
so lieben. Das ist Alt-Grrr, 7
und 0 auf deiner Tastatur.
Und ja, die sind halt geschweift.
Also die sehen aus wie so ein bisschen
wie Kuhhörner quasi, wenn du die
auf die Seite drehst.
Und wovon wir hier jetzt reden, sind eben die
eckigen Klammern. Und die
macht man quasi auf und zu und dazwischen
schreibst du dann den Bereich, den du suchen
willst. Und dann kannst du dazwischen eben so was
schreiben wie A bis Z, also wirklich
A minus Z
oder 0 minus 9.
Und die kannst du auch hintereinander schreiben in die Klammern,
um dann eben mehrere Bereiche zu suchen.
Das heißt, wenn wir sowas hätten wie beliebiger Buchstabe oder Ziffer, dann könntest du
schreiben, eckige Klammer auf, A bis Z, 0 bis 9, eckige Klammer zu.
Und dann hättest du einen, ja, Zeichenbereich definiert, der dann da an der Stelle durchsucht
wird.
Du kannst auch einfach die Buchstaben oder Ziffern oder Sonderzeichen, die du suchen
willst, einzeln aufführen, also eckige Klammer auf, A, E, I, O, U, eckige Klammer zu, würde
halt irgendein Vokal zum Beispiel suchen an der Stelle.
Und diese Bereiche sind, ja, glaube ich, so das Wichtigste, was man benutzt, zumindest,
oder was ich benutze, zumindest in meinem Alltag, weil das nämlich eben genau das ist.
Ich weiß nicht genau, welcher exakte Buchstabe oder welches Zeichen da steht, sondern ich
definiere eben so einen Bereich aus möglichen Zeichen und das kann ich eben mit diesen eckigen
Klammern machen.
So, mit diesen Bereichen kann man auch etwas negieren, wenn du als allererstes Zeichen
in deinem Bereich das Dach eingibst.
Das Dach ist immer so ein Zeichen, wie gibt man das ein?
Das ist die Taste links unter dem Escape auf deiner Tastatur, da ist einmal so ein kleiner
runder Kreis und darunter ist dieses Dach, also quasi das auf den Kopf gestellte größer
oder kleiner Zeichen, ja, und das bedeutet hier in regulären Ausdrucken quasi nicht,
das heißt, wenn du sowas machst wie eckige Klammer auf, dann dieses Dach und dann A,
E, I, O, U, eckige Klammer zu, dann suchst du nach allen Zeichen, die nicht ein Vokal
sind.
Wo könnte das sinnvoll sein in der Praxis?
Naja, nehmen wir das Beispiel mit den Vokalen.
Es gibt im Alphabet, zumindest im deutschen oder im lateinischen Alphabet, gibt es fünf
Vokale und demnach 21 Konsonanten.
Das heißt, wenn ich jetzt einen Konsonanten suche, dann müsste ich 21 Zeichen per Hand
eintippen oder ich nehme einfach die fünf und negiere die, weil dann habe ich automatisch
alles, was eben nicht Vokal entspricht.
Ist nicht ganz richtig, weil nicht Vokal heißt auch jedes andere Sonderzeichen, ja,
ich würde also auch zum Beispiel einen Strich oder sowas finden und nicht nur die Konsonanten
des Alphabets, aber es soll das einfach nur verdeutlichen, wofür man es benutzen könnte.
So, und jetzt haben wir schon ja einen ersten Eindruck, warum die regulären Ausdrücke
so komisch aussehen und so schwierig aussehen, weil wir haben jetzt schon Klammern, wir haben
schon dieses komische Dach, ja, das sind ja alles so Zeichen vielleicht, die man nicht
unbedingt im Alltag oft benutzt, ja, von daher, das sind etwas kryptische Ausdrücke, die
wir da bauen, aber wie gesagt, wenn man die Zeichen einzeln versteht, dann kann man es
gut nachvollziehen.
Und jetzt kommen wir zu zwei weiteren Zeichen, die auch ganz häufig benutzt werden, und
zwar das Zeichen für den Zeilenanfang beziehungsweise das Zeilenende.
Wenn ich zum Beispiel weiß, dass mein Text, den ich suche, immer am Zeilenanfang steht,
dann kann ich sagen, suche bitte nach Zeilenanfang und dann den Text, den ich suche, und dann
wird der Text, der nicht am Zeilenanfang steht, eben auch nicht gefunden, ja.
Beispiel aus der Praxis, ich will vielleicht alle auskommentierten Konfigurationseinstellungen
in einer Linux-Datei suchen.
Dann weiß ich, auskommentiert heißt, die fangen mit einem Hash an, das heißt, ich könnte
alle Zeilen suchen, wo am Zeilenanfang das Hash steht, und dann würde ein Hash, das
irgendwo mitten in der Zeile steht oder sonstwo, ignoriert bei der Suche, und ich würde wirklich
nur die auskommentierten Zeilen finden.
Das gleiche beim Ende von Zeilen, wenn ich weiß, keine Ahnung, ein Beispiel, was ich
gleich noch habe, am Ende von Dateizeilen habe ich irgendwie aus versehenen Leerzeichen
hingesetzt, und das will ich nicht, weil ich das unschön finde, dann kann ich alle Leerzeichen
am Ende einer Zeile suchen, das heißt, ich suche nach beliebig vielen Leerzeichen, Ende
der Zeile, und dann werden mir nur die Leerzeichen am Ende der Zeile angezeigt und nicht irgendwo
mittendrin.
Das wäre ja auch blöd, wenn ich einen normalen Text habe und da werden auf einmal alle Leerzeichen
gesetzt und nicht nur die am Ende, dann kann ich am Ende ja gar nichts mehr lesen.
Also, diese beiden Zeichen sind auch sehr wichtig, Zeilenanfang und Zeilenende, und das
Zeilenanfangszeichen in regulären Ausdrücken ist jetzt dieses DACH, was wir eben schon
bei der Negation kennengelernt haben, und das Zeilenende ist das DOLLAR-Zeichen.
Und jetzt sehen wir schon mal ein weiteres Problem mit regulären Ausdrücken, denn dieses
DACH, was wir gerade schon bei der Negation von Bereichen hatten, ist exakt das gleiche
Zeichen, was auch für den Zeilenanfang benutzt wird, das heißt, das gleiche Zeichen hat
zwei unterschiedliche Bedeutungen, und zwar abhängig davon, in welchem Kontext sie stehen.
Also, wenn man einen regulären Ausdruck mit dem DACH anfängt, dann ist das offensichtlich
das Zeilenanfangszeichen, steht das aber innerhalb von einem eckigen Klammernbereich und steht
dort als erstes Zeichen, dann ist es tatsächlich eine Negation.
Also, du musst immer gucken, welches Zeichen habe ich gerade und wo steht es, in welchem
Kontext steht es, denn abhängig davon kann die Bedeutung sich eben unterscheiden.
DOLLAR-Zeichen für Zeilenende, dafür gibt es allerdings keine zweite Bedeutung, das
ist ganz gut, also DOLLAR-Zeichen steht immer für Zeilenende.
So, und jetzt kommen wir noch mal zu einem sehr beliebten Platzhalter, und zwar dem Punkt.
Der Punkt ist so ein bisschen die Entsprechung eines Sternchens auf der Kommandozeile, obwohl
das nicht ganz stimmt, hatte ich nämlich eben schon gesagt, das Sternchen, der Asterisk
auf der Kommandozeile steht halt für ein beliebiges Zeichen, und zwar auch gleichzeitig
beliebig oft, egal wie es vorkommt, der Punkt in einem regulären Ausdruck steht aber einfach
nur für ein einziges beliebiges Zeichen, das heißt, wenn ich einen Punkt reinschreibe,
kann da irgendein Zeichen stehen, ein Sonderzeichen, ein Buchstabe, eine Ziffer, ganz egal, aber
exakt ein einziges Mal, das heißt, wenn ich drei beliebige Zeichen suche, müsste
ich eingeben, Punkt, Punkt, Punkt, und dann würde jeder Punkt für irgendein Zeichen
stehen.
Jetzt kann man sich aber überlegen, wenn ich Texte suche, die ein bisschen länger
sind, dann wird es ziemlich nervig, ganz oft Punkte da einzugeben, ja, und von daher brauchen
wir eine Möglichkeit zu sagen, ich hätte gern ein beliebiges Zeichen, aber eine bestimmte
Anzahl, beliebig oft, einmal, keinmal, wie auch immer, und dafür brauchen wir jetzt
gleich das nächste Ding, was reguläre Ausdrücke uns mitbringen, und zwar die sogenannten
Quantifizierer.
Mit diesen Quantifizierern kann man sagen, wie oft ein bestimmtes Muster vorkommen soll.
Nehmen wir mal das Beispiel mit dem Punkt, hatte ich ja gesagt, ein beliebiges Zeichen,
und wenn ich jetzt sage, ich möchte aber ganz, ganz oft dieses Zeichen haben, und zwar
zehnmal, dann könnte ich einfach hinter diesem Punkt schreiben, bitte zehnmal ein beliebiges
Zeichen.
Oder meinetwegen nullmal oder einmal, dann könnte ich einen bestimmten Quantifizierer
hinter dem Punkt schreiben, und dann wird halt ein beliebiges Zeichen null oder einmal
gesucht.
So funktionieren die.
Die Quantifizierer werden immer hinter das Muster geschrieben, was ich, ja, quantifizieren
will.
Also mit dem Beispiel Punkt, wenn ich jetzt sage, ich möchte ein beliebiges Zeichen,
aber null oder einmal, dann würde ich dafür den Quantifizierer Fragezeichen benutzen.
Dann sieht der Ausdruck so aus, Punkt, Fragezeichen.
Punkt steht für beliebiges Zeichen, Fragezeichen steht für das Muster, was davor steht, nullmal
oder einmal.
So, und das macht den Ausdruck leider schon ein bisschen komplizierter als eben das beliebte
Sternchen auf der Kommandozeile.
Also um auszudrücken, Sternchen auf der Kommandozeile, irgendein Zeichen beliebig oft, müsste ich
das in regulären Ausdrücken mit zwei Zeichen darstellen, und zwar zuerst den Punkt für
ein beliebiges Zeichen, und jetzt ist die Frage, was ist denn der Quantifizierer für
einmal oder mehrfach, weil das heißt das Sternchen eigentlich, und das wäre in regulären
Ausdrücken das Pluszeichen.
Es gibt auch das Sternchen in regulären Ausdrücken, das steht für nullmal, einmal
oder mehrfach.
Das heißt, das Zeichen kann dastehen, und wenn es dasteht, dann einmal oder mehrfach,
und das heißt Sternchen.
Das heißt, du kannst das Sternchen nicht eins zu eins aus der Kommandozeile in regulären
Ausdruck überführen.
In Dateinamen wäre es sinnvoll, wenn die Datei einen Namen hat, also das Sternchen
bin ich mir jetzt gar nicht sicher.
Ich glaube, auf der Kommandozeile matcht es auch gar keinmal.
Also wenn du einfach eine Datei heißt, die .jpg heißt, ohne Dateinamen, dann müsste
das trotzdem gefunden werden.
Das heißt, wenn du dann das Sternchen auf die regulären Ausdrücke überträgst, dann
passt es doch ganz gut, weil das Sternchen in regulären Ausdrücken steht eben für
nullmal, einmal oder mehrfach.
Das heißt, ein beliebiges Zeichen, beliebig oft, würde in regulären Ausdrücken so aussehen,
Punkt Sternchen.
Punkt, beliebiges Zeichen, Sternchen, nullmal, einmal, keinmal.
So, jetzt habe ich die drei Hauptquantifizierer eigentlich schon erklärt.
Es gibt einmal das Fragezeichen, das steht für nullmal oder einmal, also quasi entweder
ist es da oder nicht, dann gibt es das Sternchen, das für keinmal, einmal oder mehrfach da
steht und dann gibt es einmal das Pluszeichen, das wird benutzt, wenn es das Ding mindestens
einmal geben muss, aber dann beliebig oft.
So, das sind jetzt so ein paar allgemeine Platzhalter, wenn du nicht genau weißt, wie
oft Sachen da auftreten sollen.
Aber wenn du das genau weißt, dann kannst du das auch explizit hinschreiben, indem du
eine Anzahl angibst und das macht man dann mit geschweiften Klammern.
Das heißt, wenn du zum Beispiel sagen willst, ich hätte gerne das x und zwar fünfmal,
dann könntest du sagen x und dahinter die Anzahl 5 und die schreibt man in geschweifte
Klammern und da kannst du einfach die Zahl hinschreiben, die du suchst.
Also du könntest sagen x, geschweifte Klammer auf, 8, geschweifte Klammer zu, dann werden
genau 8 x-e hintereinander gesucht.
Wenn du das jetzt noch anders darstellen willst, wie zum Beispiel Minimum zweimal, maximal
fünfmal, könnte man auch das darstellen, geschweifte Klammer auf, 2,5, geschweifte
Klammer zu.
Das heißt, Minimum zwei, Maximum fünfmal.
Es kann aber auch viermal, dreimal auftreten, aber nicht einmal oder sechsmal.
Also auch eine genaue Anzahl kannst du angeben.
Um diese Quantifizierer jetzt vielleicht nochmal ein bisschen auf die Praxis zu überführen,
haben wir unser E-Mail-Beispiel.
Da hatte ich gesagt, es gibt ein Buchstaben oder Ziffer vor dem Ad, dahinter nochmal für
die Domain und dann einen Punkt und dann zwei oder drei Zeichen für die Top-Level-Domain.
Ich weiß, es gibt inzwischen längere Top-Level-Domains, kürzere bin ich mir gar nicht sicher, aber
längere auf jeden Fall.
Trotzdem bleiben wir mal bei diesem vereinfachten Beispiel.
Dann könnte ich sowas machen wie, das Zeichen vor dem Ad kann irgendein Buchstabe oder Ziffer
sein.
Also gebe ich an, Eckjehl-Klammer auf, a-z, 0-9, Eckjehl-Klammer zu.
Damit habe ich irgendein Buchstaben oder eine Ziffer.
Und jetzt muss ich noch sagen, wie oft die da stehen muss.
Und jetzt möchte ich, dass es mindestens einmal da steht, denn sonst habe ich keine
gültige E-Mail-Adresse.
Wenn da irgendwie steht, Ad irgendwas, dann fehlt da vor dem Ad was, d.h. da muss mindestens
ein Zeichen stehen.
Also würde ich ein Plus-Zeichen dahinter schreiben, also hinter die eckigen Klammern
einmal das Plus.
D.h. Ziffer oder Buchstabe beliebig oft, aber mindestens einmal.
Dann gebe ich das wörtliche Ad-Zeichen ein, weil da muss wirklich ein Ad-Zeichen stehen.
Dahinter sage ich jetzt einfach mal, Domains dürfen nur aus Buchstaben bestehen.
Ist auch nicht richtig, aber geben wir mal davon aus.
Dann würde ich hier wieder einen Bereich machen, also Eckjehl-Klammer auf, a-z, Eckjehl-Klammer
zu.
Und auch hier muss mindestens einmal ein Buchstabe drin sein, sonst habe ich keine
gültige Domain.
Also mache ich wieder ein Plus dahinter.
Jetzt kommt der Punkt.
Wir erinnern uns, Punkt heißt beliebiges Zeichen.
Ich möchte aber, dass an dieser Stelle wirklich der wörtliche Punkt steht und nicht irgendein
anderes Zeichen.
Also muss ich den Punkt dahin schreiben, aber escapen mit einem Backslash.
Also Backslash, Punkt.
Und dann kommt die Top-Level-Domain und da sage ich jetzt, ich möchte wieder einen Bereich
haben, Eckjehl-Klammer auf, a-z, Eckjehl-Klammer zu.
Und jetzt schreibe ich dahinter aber in geschweiften Klammern 2,3.
Und das bedeutet, ich habe zwar Buchstaben, aber mindestens zwei und maximal drei.
Wie gesagt, das würde nicht auf echte Domains zutreffen, aber für das Beispiel, ich hoffe,
du kannst mir das verzeihen.
Und dann hätten wir in diesem simplen Ausdruck schon verschiedene Sachen drin, nämlich Bereiche,
Quantifizierer, exakte Quantifizierer oder eben sowas wie Plus, um beliebig oft zu suchen,
aber mindestens einmal.
Und wir müssen den Punkt escapen, weil er sonst für was anderes stehen würde.
Das heißt, schon der reguläre Ausdruck für eine simple E-Mail-Adresse sieht relativ
kompliziert aus, mit ziemlich vielen Sonderzeichen, die alle eine besondere Bedeutung haben, aber
ich hoffe, du liest das im Nachgang nochmal nach und kannst das dann verstehen und das
dann in Zukunft auch vernünftig anwenden, sage ich mal.
So, zwei Sachen habe ich noch, die man öfter sieht oder benutzt in regulären Ausdrücken,
und zwar einmal Alternativen und Gruppen.
Wir gucken uns zuerst die Alternativen an, die sind schnell erklärt.
Und zwar, wenn du unterschiedliche Muster suchst und es kann entweder das eine oder
das andere auftreten, dann kannst du die mit so einer Art Oder-Zeichen verbinden.
Aus der Programmierung kennst du vielleicht die doppelte Pipe, also diesen horizontalen
Strich für ein logisches Oder.
Und etwas ähnliches wird hier auch benutzt, nämlich die Pipe, aber nur eine davon.
Jetzt könntest du zum Beispiel sagen, ich suche entweder das A oder das B, dann könntest
du aufschreiben A-Pipe-B und dann steht das eben für die Alternative.
Entweder steht hier ein A oder da steht ein B.
Beziehen wir das nochmal auf unser Beispiel mit dem Herrn Meier oder der Frau Meier, die
wir in unserem Text suchen, dann könntest du auf die Idee kommen, zu sagen, ich hätte
ein großes M, dann machst du eckige Klammern auf und machst da A, E, I, Y, was da so erlaubt
ist, eckige Klammern zu, und ein R am Ende.
Und dann hättest du alle Schreibweisen von Meier gesucht, oder, äh, sorry, hinter die
eckige Klammer hättest du noch einen Quantifizierer schreiben müssen, nämlich einen Plus, oder
bis hin zu wahrscheinlich sogar zwei bis drei oder so, weil mehr würdest du sonst ja auch
finden, M-E-R, aber du brauchst ja I-E-R, also E-E-I, also mehrere Zeichen, das heißt,
du müsstest noch einen Quantifizierer dahinter schreiben.
Aber lass mir das mal weg.
Du könntest auch sagen, ich kenne alle Schreibweisen von Meier und schreibe die als Alternative
auf.
Das heißt, ich suche entweder Meier mit E-I-E, Pipe, Meier mit A-Y-E-R, Pipe, Meier mit,
ich weiß nicht, Y-E-I, keine Ahnung was, du könntest also alle, die du kennst, hintereinander
einfach aufschreiben und eine Pipe dazwischen schreiben, und dann würdest du ja auch alle
möglichen Schreibweisen finden.
Ist eine längere Variante als das mit dem Buchstabenbereich, ja, würde aber auch funktionieren.
So, und jetzt kommen wir zum letzten Part, und das ist eigentlich das, wofür ich es
in der Praxis am häufigsten benutze, die regulären Ausdrücke, und zwar für die Gruppierung,
für die Gruppen.
Du kannst mit den ganz normalen, runden Klammern Gruppen bilden, und das bedeutet, dass Teile
deines regulären Ausdrucks oder auch der Ganze, den kannst du in Klammern schreiben,
und dann merkt sich der reguläre Ausdruck bei jedem Muster, was er findet im Text, genau
diese Teile des Suchmusters.
Ich nehme mal ein Beispiel.
Bleiben wir bei der E-Mail-Adresse, wenn du wissen willst, was für Domains zum Beispiel
in den E-Mail-Adressen vorkommen, ja, also gmx.de, web.de, keine Ahnung, itberufepodcast.de,
dann könntest du deinen regulären Ausdruck so aufbauen, dass du beliebige Zeichen suchst
und ein Add-Zeichen, genau wie eben auch, aber dann machst du über alles hinter dem
Add-Zeichen quasi eine Gruppe, indem du runde Klammern davor und dahinter schreibst, und
dann würde sich der reguläre Ausdruck, wenn er eine E-Mail-Adresse findet, merken, dass
der Teil hinter dem Add-Zeichen, ja, in diesem Fall eine Gruppe bildet, und dann könntest
du zum Beispiel in deiner Programmiersprache oder in deinem Texteditor auf diese Gruppe
zugreifen und die dann besonders behandeln, zum Beispiel ausgeben oder ersetzen oder sonst
irgendwas.
Und wenn du also aus einer Liste der E-Mail-Adressen alle Domains rausfinden willst, könntest
du eben nach diesen E-Mail-Adressen suchen und könntest dann auf die Gruppe zugreifen,
wo die Domain drin steht, und die dann zum Beispiel ausgeben lassen.
Und schon hättest du eine Liste aller Domains von deinen E-Mail-Adressen, ohne das, was
davor stand.
Also die ganzen, was weiß ich, Stefan, Macke, Ed, das würde alles abgeschnitten und nur
die Domain würde übrig bleiben.
Also kannst du wirklich auf die, ja, Innereien quasi dieses gesuchten Textes zugreifen und
die dann beliebig wiederverwenden.
Ich nehme mal ein Beispiel aus der Praxis, du hast eine Liste aus Vornamen und Nachnamen
mit Leerzeichen getrennt, wir gehen mal davon aus, dass es keine Doppelnamen gibt oder sonst
irgendwas, auch wieder sehr reduziert das Beispiel, ja, aber wenn du die quasi ersetzen
wolltest durch Nachname, Vorname, dann könntest du das mit so einer Gruppe machen.
Also stellen wir uns vor, Liste aus Vornamen, Leerzeichen, Nachnamen, dann sieht dein Muster
ungefähr so aus, beliebiges Zeichen oder beliebig viele Zeichen, Leerzeichen, beliebig
viele Zeichen.
Und jetzt würdest du diese beiden beliebig viele Zeichen einfach in Klammern schreiben
und dann würde er quasi die erste Gruppe für den Vornamen bilden und die zweite Gruppe
für den Nachnamen und dazwischen steht halt das Leerzeichen.
Und wenn du jetzt danach suchst, wie gesagt, merkt sich der reguläre Ausdruck diese beiden
Gruppen und wenn du jetzt zum Beispiel sagst in deinem Editor, ich möchte das jetzt ersetzen,
dann kannst du in diesem Ersetzen-Ausdruck auf diese Gruppen referenzieren.
Und je nachdem, welchen Editor du da benutzt, ist die Syntax ein bisschen unterschiedlich.
In den meisten Editoren wird das mit einem Backslash gemacht, Backslash 1 ist zum Beispiel
die erste Gruppe, Backslash 2 die zweite und so weiter.
Ich kenne aber auch Editoren, wo man das dann mit einem Dollarzeichen macht, also Dollarzeichen
1, Dollarzeichen 2, wie die Variablen Namen PHP zum Beispiel.
Und diese, ja, Variablen, in Anführungszeichen, die kannst du dann zum Ersetzen benutzen.
Das heißt, wenn du vorher sagst, Gruppe 1, Leerzeichen, Gruppe 2, dann ist Gruppe 1
der Vorname, Gruppe 2 ist der Nachname.
Und wenn du es jetzt ersetzt durch Backslash 2, Leerzeichen, Backslash 1, dann wird er
den Nachnamen nach vorne schreiben, Komma, Leerzeichen dahinter und dahinter den Vornamen.
Dann hättest du quasi Vor-Nachname vertauscht mit einem simplen regulären Ausdruck.
Das heißt, immer wenn du runde Klammern in deinem regulären Ausdruck siehst, dann weißt
du, aha, hier wird gerade eine Gruppe gebildet und die brauchst du eigentlich fast nur, wenn
du suchen und ersetzen willst.
Wenn du nur suchen willst, sind die Gruppen irrelevant, ja, aber wenn du mit diesem Suchergebnis
irgendwas anstellen willst, das ausgeben willst, verarbeiten willst, ändern willst,
wie auch immer, dann musst du es halt gruppieren, um auf die Teile deines Ausdrucks zugreifen
zu können.
So, damit haben wir jetzt erstmal die wichtigsten Inhalte von regulären Ausdrücken oder die
wichtigsten Beispiele, um Muster zu definieren.
Es gibt noch ein paar mehr, wie gesagt, die geben wir jetzt hier alle nicht im Detail durch,
das führt zu weit, aber ich wiederhole nochmal so ein paar allgemeine Sachen, die man jetzt
benutzen kann.
Wenn du irgendein Zeichen eingibst, wird das exakt so gesucht.
Außer, es ist ein Sonderzeichen, was eine besondere Bedeutung hat, dann musst du es
escapen und zwar mit dem Backslash.
Wenn du Zeilenanfang und Zeilenende suchst, sind das das Dach bzw. das Dollarzeichen.
Wenn du einen Bereich von Zeichen suchst, also A bis Z oder 0 bis 9 oder sonst irgendwas,
dann machst du eckige Klammern dadrum.
Wenn das erste Zeichen in diesen eckigen Klammern ein Dach ist, ist das eine Negation, das heißt,
es wird alles gesucht, was nicht diesem Bereich entspricht.
Wenn du bestimmte Alternativen suchen willst, also A oder B oder C oder wie auch immer,
kannst du Pipes dazwischen schreiben.
Wenn du irgendein beliebiges Zeichen suchen willst, ganz egal, was für eins, auch inklusive
Sonderzeichen usw., nimmst du den Punkt.
Der Punkt steht für irgendein Zeichen.
Und wenn du jetzt die Sachen, die du da angegeben hast, quantifizieren willst, also wie oft
sie auftreten, dann gibt es jeweils die verschiedenen Quantifizierer, die hinter das Muster geschrieben
werden, und da gibt es das Fragezeichen, einmal oder keinmal, dann gibt es das Sternchen,
nullmal, einmal oder mehrfach, und das Pluszeichen, einmal oder mehrfach.
Und wenn du es ganz genau angeben willst, kannst du es in geschweifte Klammern schreiben
und einfach eine Zahl angeben, also geschweifte Klammer auf 8, geschweifte Klammer zu exakt
8 mal, oder geschweifte Klammer auf 2,5, geschweifte Klammer zu 2 bis 5 mal, also auch 3 oder 4
mal.
Und wenn du dann Teile deines Ausdrucks benutzen willst, um sie zum Beispiel zu ersetzen oder
sonst irgendwas, dann gruppierst du diese Teile bitte mit runden Klammern, die du einfach
um den Ausdruck drumherum schreibst.
Und die Referenz ist dann, je nach Editor, entweder backslash 1234, je nachdem, welches
Muster es ist, oder dollar 1234 und so weiter.
So, jetzt habe ich lange erklärt, wie die Syntax von den regulären Ausdrücken aussieht,
und jetzt bringe ich mal ein paar Beispiele aus meiner Praxis, die ich noch so im Kopf
hatte aus den letzten Tagen und Wochen, was ich da so im Alltag mitmache.
Dann gehe ich jetzt einfach mal wahllos von oben nach unten durch und erkläre mal, was
der Sinn dahinter war.
Ich hatte eine riesengroße Textdatei, in der ganz, ganz viele UUIDs drin waren.
UUIDs, wenn du es noch nie gehört hast, sind so auf Knopfdruck generierte IDs in Hexadezimalschreibweise,
die global eindeutig sind.
Die sind ziemlich lang und die kann normalerweise jede Programmiersprache erzeugen und die werden
häufig in Datenbanken zum Beispiel benutzt, um dort Datensätze eindeutig mit Schlüsseln
zu versehen.
Und ich hatte eben so eine große Textdatei und sollte die alle raussuchen, weil ich damit
was machen musste.
Und dann kann man bei diesen UUIDs ziemlich genau dieses Muster definieren, wie die aufgebaut
waren.
Das ist, wie gesagt, eine sehr lange Hexadezimalkette und ich konnte einfach sagen, die Hexadezimalzeichen
sind immer A-Z oder 0-9, beziehungsweise, sorry, ich sehe gerade in meiner eigenen Aufzeichnung,
dass das Muster Quatsch ist, natürlich, Hexadezimalzeichen gehen nicht bis Z, sondern bis F, wie Friedrich.
Das heißt, das Muster muss so aussehen, A-F, 0-9 und dann kann ich genau sagen, wie dieses
UUID-Ding aufgebaut ist und zwar sind das immer Blöcke von Hexadezimalziffern, dann
kommen immer Bindestriche dazwischen und das dann ein paar Mal hintereinander.
Und so konnte ich einfach sagen, die UUIDs sind so aufgebaut, Hexadezimalzeichen und
das ist eben A-F, 0-9 und dahinter dann in geschweifenen Klammern die genaue Anzahl.
Und in meinem Fall waren es dann halt einmal 8 Zeichen, minus 4 Zeichen, minus 4 Zeichen,
minus 4 Zeichen, minus 12 Zeichen.
So war die in meiner Datei aufgebaut.
Der Ausdruck ist also schon etwas länger, der ist aber ziemlich einfach, weil es ist
immer das gleiche Muster, nur mit Bindestrichen und einem Quantifizierer abgetrennt.
Und so konnte ich dann exakt die UUIDs rausfiltern und die in eine andere Datei schreiben und
damit dann das tun, was ich tun wollte.
So, nächstes Beispiel, bin ich schon ein paar Mal drauf rumgeritten, E-Mail-Adressen
suchen.
Sieht auch relativ einfach aus, eckige Klammern, A-Z, eckige Klammern zu, Plus, dann das Add,
dann nochmal Zeichen, Plus, Backslash, Punkt und dahinter dann eben die Zeichen 2-3 Mal
für die Top-Level-Domain.
Hatten wir jetzt schon ein paar Mal, gehe ich jetzt hier nochmal im Detail durch.
Vorname-Nachname-Vertauschen ist wirklich etwas, was ich häufig habe, das habe ich
gerade auch schon kurz erklärt.
Der reguläre Ausdruck sieht relativ einfach aus.
Haben wir Vorname, Leerzeichen, Nachname, dann sieht der Ausdruck so aus.
Runde Klammer auf, Punkt, Plus, Runde Klammer zu, Leerzeichen und dann nochmal genau das
gleiche. Runde Klammer, Punkt, Plus, Runde Klammer zu. Punkt, Plus steht für ein beliebiges
Zeichen. Das ist der Punkt. Beliebig oft, aber mindestens einmal. Dafür das Plus. Und
weil ich die ja jetzt gleich vertauschen will, brauche ich Gruppen, um dann darauf zugreifen
zu können. Deswegen packe ich beide Sachen in Runde Klammern und dann kann ich das Ding
ersetzen durch $2, $1 und dann habe ich Nachname, Vorname daraus gemacht. Dein Anwendungsfall,
den ich auch ganz oft hatte, was weiß ich, Sourcecode mit einem komischen Editor bearbeitet,
am Ende der Sourcecode-Zeilen blieben immer Leerzeichen stehen und das ist unschön. Das
sollte man nicht machen. Dann kann man einfach alle Leerzeichen am Ende einer Zeile ersetzen.
Und der reguläre Ausdruck dafür sieht so aus. Leerzeichen plus Dollar. Leerzeichen
plus steht für Leerzeichen, beliebig oft, aber mindestens einmal und Dollarzeichen steht für
Zeilenende. Das heißt, nur die Leerzeichen am Zeilenende sollen gefunden werden. Das ersetzt
sich dann durch Nichts und dann habe ich alle Leerzeichen am Ende entfernt. Ganz oft habe ich
sowas wie, ich möchte, was weiß ich, einen Artikel schreiben für den Blog oder so und da habe ich
Aufzählungslisten drin und je nachdem, in welchem System ich gerade bin, werden die unterschiedlich
geschrieben. Mal mit einem Sternchen, mal mit einem Minus, mal mit einem Punkt, wie auch immer. Und
wenn ich sowas habe, dann kann ich relativ einfach für alle Zeilen, die ich gerade aufzählen will,
mit einem simplen Ausdruck das Aufzählungszeichen davor schreiben. Ja, also stell dir vor, ich habe
einen Texteditor auf, da sind 27 Zeilen drin und ich will jetzt vor jeder dieser Zeile meinetwegen
ein Sternchen schreiben, weil ich in Markdown das Ding als Aufzählung habe. Dann gehe ich jetzt
nicht durch 27 Zeilen und füge da überall ein Sternchen ein, sondern ich suche einfach nach dem
regulären Ausdruck Dach. Und das Dach hast du schon kennengelernt, wenn das so alleine steht
und nicht in einem Bereich, steht das für Zeilenanfang. Das heißt, ich suche nach dem
Zeilenanfang und ersetze den durch Sternchen Leerzeichen. Und wenn ich das mache, habe ich mit
drei Zeichen in alle 27 Zeilen ein Sternchen und ein Leerzeichen eingefügt. Also, das kriegst du
per Hand, glaube ich, nicht so schnell hin. Wichtig bei sowas, es kommt dann immer auf deinen Editor an,
wenn du Sonderzeichen als Ersetzung benutzt, wie zum Beispiel dieses Malzeichen, also den Asterisk,
den ich da einfügen will, den kennst du aus regulären Ausdrucken, der hat dann eine besondere
Bedeutung, da ist er nämlich ein Quantifizierer für 0, 1 oder mehrfach. Und je nachdem, wie dein
Editor funktioniert, musst du dieses Sternchen beim Ersetzen eventuell auch escapen. Das heißt,
anstatt zu schreiben, ersetze den Zeilenanfang durch Sternchen Leerzeichen, müsstest du eventuell
schreiben, ersetze durch Backslash Sternchen Leerzeichen, weil das Sternchen sonst wieder
interpretiert wird. Also, das kommt auf den Editor an. Manche machen das, manche nicht.
Und als Ergebnis habe ich dann eben vor jeder Zeile meiner Textdatei ein Asterisk stehen und kann das
Ding eins zu eins, das Markdown, irgendwohin kopieren zum Beispiel. So, was ich dann auch
tatsächlich häufiger mal habe, gerade wenn ich so Schnittstellen programmiere in Java zum Beispiel,
dann gibt mir vielleicht irgendwer eine Liste an Attributen, die ich dann in meine Klasse reinpacken
soll und dann zum Beispiel als private Felder definieren soll. Dann habe ich vielleicht eine
Liste mit auch wieder 27 Zeilen, wo dann sowas drinsteht wie Alter der Person in Jahren oder
Farbe oder Hersteller oder ich weiß nicht was. Einfach beliebige Zeichenkeppen. Und daraus möchte
ich jetzt in meiner IDI private Felder machen. Also aus Alter der Person in Jahren möchte ich
machen private Integer Alter der Person in Jahren Semikolon, damit das halt eine gültige Variablen
Deklaration wird. Und das kann ich jetzt relativ einfach machen. Ich suche einfach nach allem,
was in der Zeile steht. Das mache ich mit Punkt Plus, beliebiges Zeichen, beliebig oft,
aber mindestens einmal. Und das ganze Ding gruppiere ich, weil ich es gleich beim Ersetzen
brauche. Das heißt, der reguläre Ausdruck sieht so aus. Klammer auf, Punkt Plus, Klammer zu.
Relativ easy. Und das ersetze ich jetzt durch private Leerzeichen, Integer, Leerzeichen und
dann $1 für die erste Gruppe, also alles, was ich in der Zeile gefunden habe, und Semikolon.
Und dann sucht er mir den gesamten Zeileninhalt und ersetzt das durch private Integer,
Zeileninhalt, Semikolon. Relativ einfach, auch nur ganz wenig, was ich eintippen muss und schon
spare ich mir einen Riesenhaufen Tipperei in meiner IDI. Das Beispiel könnte ich auch anders
lösen. Es ist nur ein Beispiel. Da muss man immer wissen, was dann schneller geht. Viele
IDIs haben auch so einen Blockmodus. Das heißt, ich kann, wenn ich tippe, den Cursor nicht nur
in einer Zeile zum Einfügen benutzen, sondern in mehreren. Und dann würde ich zum Beispiel in der
IDI diesen Blockmodus aktivieren, markiere die 27 Zeilen, wo ich was vorschreiben will, tippe das
einmal ein und die IDI gibt das automatisch überall in den 27 Zeilen ein. Das wäre eine
Alternative dazu. Ich weiß, dass das geht, aber ein Beispiel für reguläre Ausdrücke ist das hier
trotzdem ganz gut. Denn, wenn wir mal weiterdenken, der Blockmodus erfordert, dass man immer an der
gleichen Stelle in der Zeile steht. Wenn die Variablen alle eine unterschiedliche Länge
haben, weil die Namen unterschiedlich lang sind, dann geht das mit dem Blockmodus vielleicht nicht
mehr. Und gerade beim Ende der Zeile, wo das Semikolon ja hin muss, ist es dann vielleicht
nicht ganz so einfach, das mit dem Blockmodus zu machen in der IDI. Mit dem regulären Ausdruck
geht das trotzdem. So, dann zum Ende noch das Komplexes, oder kompliziert ist es eigentlich nur
komplex ist es ja nicht. Kompliziertes Beispiel und zwar mache ich ganz oft, ja zum Beispiel für
den Block hier oder so, irgendwelche Linklisten oder irgendwas und da habe ich oft die Anforderung,
dass ich zum Beispiel HTML und Markdown oder Textile oder Wikisyntax oder wie auch immer hin
und her konvertieren muss. Und das kann man auch sehr einfach mit regulären Ausdrücken machen. Und
zwar sieht der Ausdruck dann vielleicht ein bisschen komplizierter aus. Ich gehe jetzt hier
auch nicht im Detail durch, kann es dir auf der Website mal angucken, aber im Prinzip, wenn ich
zum Beispiel HTML-Links suche und daraus Markdown-Links machen will, dann definiere ich einfach, okay,
in HTML sehen Links so aus, Spitze Klammer, A, href gleich und dann die URL in Anführungszeichen,
Spitze Klammer zu, dann kommt eben wie ein Text, der da verlinkt wird und dann nochmal das schließende
A-Tag. So, das kann ich jetzt suchen und dann suche ich einmal die URL als Gruppe und einmal
den Text als Gruppe, sodass ich also aus diesem HTML-Link die URL und die Beschreibung oder den
Titel halt eben extrahieren kann. Und dann ersetze ich das einfach durch die Markdown-Syntax und
benutze $2 und $1 an der Stelle, wo die URL oder der Titel halt hin soll. Und so kann ich tatsächlich
auf Knopfdruck aus allen HTML-Links Markdown-Links machen. Oder auch umgekehrt. Oder ich mache
Markdown zu Texteilen oder wie auch immer. Also genau für solche Transformationen ist es sehr
einfach, mal eben schnell den Regex zu schreiben und dann ist das mit einem Klick quasi gesucht
und ersetzt. So, das waren jetzt erstmal alle Beispiele. Kannst du dir nochmal im Detail auf
der Website angucken, in den Shownotes. Da habe ich dir nochmal mit der genauen Syntax dargestellt,
kannst dir mal in Ruhe durchschauen und versuchen, das zu verstehen. So, bevor wir jetzt gleich hier
zumachen, haben wir nochmal einen kurzen Ausblick, wo du vielleicht reguläre Ausdrücke nicht für
benutzen solltest. Und ein Beispiel, was ich gerade genannt habe, gehört schon dazu. Und zwar HTML
auseinandernehmen. Wenn du auf die Idee kommst, HTML mit regulären Ausdrücken zu durchsuchen oder zu
ersetzen oder sonst irgendwas, dann ist das eine ganz, ganz schlechte Idee. Ich habe dir auch einen
schönen Artikel verlinkt, wo das genau erklärt wird, warum das eine schlechte Idee ist. Ganz
kurz zusammengefasst. Reguläre Ausdrücke sind nicht dafür geeignet, Sprachen zu parsen wie
HTML. Es gibt die sogenannte Chomsky-Hierarchie. Die habe ich auch in den Shownotes verlinkt. Die
kannst du dir mal angucken. Und ja, wenn man so will, werden so Sprachen so ein bisschen eingegliedert
in ganz einfache Sprachen bis hin zu komplizierten Sprachen. Was auch immer das jetzt heißt, das führt
jetzt hier zu weit. Das will ich nicht auseinandernehmen. Auf jeden Fall arbeiten reguläre
Ausdrücke auf einer Ebene und HTML arbeitet auf einer höheren Ebene. Das heißt, du kannst mit
regulären Ausdrücken HTML nicht auseinandernehmen. Ein ganz einfaches Beispiel. Angenommen, du suchst
irgendwelche Tags und den passenden schließenden Tag dazu. Das muss in HTML ja immer so sein. So
was kannst du mit regulären Ausdrücken nicht exakt abbilden. Dafür sind die nicht gedacht. Das
funktioniert dort einfach nicht. Wenn du jetzt auf die Idee kommst, das zu tun, solltest du das
sein lassen und stattdessen einfach ein HTML-Parser nehmen. Dafür sind die gebaut. Und XML ist das
gleiche. HTML, XML. Das nimmt man nicht mit regulären Ausdrücken auseinander, sondern mit
einem entsprechenden Parser. Mein Beispiel von eben aus HTML links markdown machen. Das funktioniert.
Ja, und für mein simples Beispiel und in einer Textdatei, die ich unter meiner Kontrolle habe
und wo ich weiß, dass alles korrekt ist, da kann ich das auch machen. In einem Programm, was fehlerfrei
funktionieren muss mit beliebigen Eingaben, darfst du bitte nicht HTML mit regulären Ausdrücken
auseinandernehmen. Das funktioniert nicht. Dafür brauchst du einen Parser. Bringt aber auch ja jede
Promisprache eigentlich mit. Von daher sollte das kein Problem sein. Und zweites Problem. Reguläre
Ausdrücke können relativ teuer werden. Denn wie funktionieren die Dinger? Ich habe gerade schon gesagt,
das ist quasi eine eigene Sprache. Und reguläre Ausdrücke werden in einen Zustandsautomaten
überführt, der dann den Text auseinander nimmt. Und das ist relativ aufwendig. Auch wenn die
Muster vielleicht relativ einfach aussehen. Was dahinter steckt, da muss der Rechner ganz schön
viel leisten quasi. Und wenn du jetzt also performancekritische Anwendungen baust, wo es
auf jeden Millisekunden ankommt quasi, dann solltest du vielleicht lieber nicht
reguläre Ausdrücke benutzen. Weil, wie gesagt, die sind ziemlich teuer im Vergleich zu normalen
Suchen und Ersetzen zum Beispiel. Oder zu, keine Ahnung, mit Substrings in irgendwelche Strings rein
friemeln. Das ist tausendmal performanter als ein regulärer Ausdruck. Ich habe auch noch mal
einen schönen Artikel verlinkt. Stackoverflow, die Seite kennst du bestimmt. So die Nummer 1 für
Softwareentwickler, wenn du nach irgendwas suchst. Und die hatten tatsächlich mal eine Downtime, weil
ein regulärer Ausdruck die Seite zum Absturz gebracht hat, weil der so teuer war, dass alle
Rechner sich zu Tode gerechnet haben. Also das ist ein reelles Problem in der Praxis und das
kannst du dir gerne mal durchlesen. Ist schon ein paar Jährchen her, dass das passiert ist, aber das fand ich ein
schönes plakatives Beispiel dafür, dass man nicht alles mit regulären Ausdrücken lösen sollte. Wie
gesagt, denk an den goldenen Hammer. Reguläre Ausdrücke sind cool, aber sind nicht die Lösung
für alles. Also HTML, XML auseinandernehmen und performancekritische Sachen lieber nicht mit
regulären Ausdrücken machen. So, dann noch mal eine ganz kurze Liste an Programmen, die vielleicht,
ohne dass du es weißt, reguläre Ausdrücke unterstützen. Wenn du mal darauf achtest, wirst du
feststellen, dass so gut wie jeder vernünftige Texteditor reguläre Ausdrücke unterstützt. Auch alle
möglichen Kommandozeilen und IDEs insbesondere, die unterstützen das auch. Also Kommandozeile,
die Bash zum Beispiel oder die PowerShell, die unterstützen alle reguläre Ausdrücke. Die
PowerShell zum Beispiel mit dem Commandlet SelectString oder die Bash zum Beispiel mit
GREP. GREP ist so das Standard-Tool, um nach regulären Ausdrücken in Dateien zu suchen. Dann
Editoren, der VI natürlich, Notepad++, Visual Studio Code, Atom, was auch immer,
Emacs natürlich. Also alle guten Texteditoren unterstützen Suchen und Ersetzen mit regulären
Ausdrücken. Und IDEs, Eclipse, IntelliJ für Java oder Visual Studio oder ich weiß es nicht, PHP
Storm oder was es noch so gibt, die werden alle reguläre Ausdrücke unterstützen. Also wenn du
dieses Werkzeug beherrscht, bist du unabhängig von irgendeinem konkreten Texteditor, weil die
regulären Ausdrücke funktionieren überall gleich. Du musst sie nur einmal lernen und dann kannst
du sie in beliebigen Editoren, IDEs, Shells, wie auch immer, verwenden. Das zeigt noch mal,
dass es so ein verbreitetes Tool ist, dass du das unbedingt lernen solltest, meiner Meinung nach.
Und damit das auch funktioniert, habe ich, wie gesagt, ein paar Links zusammengetragen. Die
kannst du gerne noch mal durchlesen. Da gehe ich jetzt nicht alle im Detail durch. Und in Kapitel
10, zumindest in der aktuellen Ausgabe, des IT-Handbuchs für Fachinformatiker von Sascha
Kersken, hat er auch eine mehrseitige Einführung in reguläre Ausdrücke mit Java und Python als
Programmiersprachen. Von daher sehr praxisnah, mit schönen Beispielen und auch wirklich im Detail
erklärt. Also wenn du das sowieso liest, was ich hoffe, wenn du IT-Azubi bist, dann guck dir das
Kapitel doch mal an. Da ist eine schöne Einführung in das Thema reguläre Ausdrücke mit genauer
Syntax, mit Beispielen und wie man es in der Programmierung anwendet. Also besser geht es
eigentlich nicht. Von daher brauche ich gar kein zusätzliches Buch empfehlen. Nimm einfach das,
was du sowieso schon hast, das IT-Handbuch und guck es dir da an. So, damit mache ich jetzt mal zu.
Ich habe schon über 50 Minuten, das ist auch mein Herzensthema. Wie gesagt, ich habe es am Anfang
gesagt, ich kann es nur empfehlen. Guck dir das an, reguläre Ausdrücke, super Tool und du kannst
es an sehr vielen Stellen verwenden. Und wenn du es erstmal beherrschst, werden dir auch immer noch
mehr Stellen auffallen, wo du es tatsächlich einsetzen kannst. Von daher schnapp dir das Buch,
guck dir das an, übe das mal und ich habe auch noch ein paar Links auf der Website, wie gesagt,
itberufepodcast.de. Da findest du das alles, da findest du meine Beispiele und auch die Links zu
zwei super Websites, wo, wenn du einen regulären Ausdruck eingibst, der wirklich bis auf die
einzelnen Zeichen auseinandergenommen wird, mit Farben hinterlegt wird und so weiter,
was die heißen. Besser kannst du reguläre Ausdrücke eigentlich gar nicht lernen. Von
daher, schau da gerne mal vorbei. Und ich würde mich freuen, wenn du mir auch ein Feedback gibst,
wofür du reguläre Ausdrücke einsetzt oder hast du noch nie was von denen gehört. Auch dann würde
es mich freuen, wenn du mich informierst. Schick mir eine Mail oder schreib mir eine E-Mail über das
Kontaktformular oder such mich bei Twitter, Facebook, LinkedIn, wie du willst. Hauptsache,
ich höre von dir. Würde mich freuen. So, damit mache ich heute mal den Laden zu.
Ich sage vielen Dank für die Aufmerksamkeit und bis zum nächsten Mal. Tschüss!










Schöner Einstieg ins Thema, hätte nicht gedacht dass das in einen Podcast so möglich ist, Respekt!
Ich verwende oft noch die vordefinierten Zeichenklassen \s und \w bzw. deren Umkehrung \S und \W.
Hallo Michel, das freut mich, danke! Deine Ergänzungen finde ich auch spannend. Die genannten, insb.
\s, nutze ich auch sehr oft. Ich musste nur irgendwo die Grenze für die Episode ziehen. Danke für den Hinweis!