Werbung einblenden Werbung ausblenden


Home / Tutorials / Perl Handbuch / Regular Expressions

Was sind Regular Expressions?
$_ als Default Wert
der Binding Operator
Optionen: i und g
Die mit Regular Expression übereinstimmenden Textteile abfangen: $1
Angeben wie oft ein Zeichen vorkommen soll: + und *
+ und * sind im Default greedy
Umstellen auf nicht greedy: ?
Was ist eigentlich ein Wordelement(\w)?
Kurzschreibweise für irgendeine Zahl: \d anstatt [0-9]
Präzise angeben, wie oft ein Zeichen vorkommen soll: {mindestens,höchstens}
Gruppen bilden: [das Zeichen | oder jenes | oder dieses]
Anker setzen: ^ und $
Den Inhalt der eckigen Klammer negieren: ^
Praktisches Beispiel: Prüfen ob es sich um eine email Adresse handelt
Praktisches Beispiel: Den Namen eines Bildes ermitteln
Regular Expressions in Verbindung mit substitution, split und grep
Praktisches Beispiel: HTML Tags eliminieren
Praktisches Beispiel: Links in den image tag einbinden
Praktisches Beispiel: Mit grep und Regular Expression bestimmte Elemente eines Arrays finden
Zusammenfassung

Was sind Regular Expressions?

Die Regular Expressions gehören zu den wichtigsten und mächtigsten Funktionen von Perl. Die Verbreitung von Perl im Internet dürfte auf die Regular Expressions zurückzuführen sein. Hier hat man es selten mit mathematischen Problemen zu tun. Meistens geht es darum, Texte in der einen oder anderen Weise zu manipulieren. Dabei sind die Regular Expressions ein enorm leistungsfähiges Tool. Sie sind die abstrakte Formulierung, eines bestimmten Typs von Text. Geniale Erklärung? Hier ein Beispiel: Wir haben drei Zeichenketten.
1. Die Affen rasen durch den Wald, der eine macht den anderen kalt, die ganze Affenbande singt .....
2. Die Affen, die nächsten Verwandten des Menschen, sind als Babys lange nicht so putzig wie kleine Hunde.
3. Wenn manche Affen deprimiert sind, dann ist das eine deprimierende Erkenntnis.

Wir haben also einen bestimmten Typ von Text vor uns, der folgendermaßen strukturiert ist. Zu Beginn kommen ein paar Buchstaben, dann kommt das Wort Affen, dann wieder eine ganze Portion Buchstaben. Die Regular Expression dazu ist also eine Portion Buchstaben, dann das Wort Affen, dann eine Portion Buchstaben. Solche Elemente findet man oft. Email-Adressen haben eine bestimmte Struktur, Hyperlinks haben eine bestimmte Struktur, Html Seiten haben eine bestimmte Struktur etc. etc.. Alles, was irgendwie eine wie auch immer geartete Struktur hat, lässt sich mit Regular Expressions manipulieren. Regular Expressions können auch dann noch verwendent werden, wenn der Text nur schwach strukturiert ist.
Der einfachste Fall einer Regular Expression sieht so aus:

Anwendungen - Beispiele

$_ als Default Wert

$banane="Every beat of my heart brings me further apart.";
$_=$banane;
$test=m/heart/;
print $test;

Erklärungsbedürftig? Der Match Operator (m) geht im Default auf die Sondervariable $_. Die kennen wir schon aus Funktionen zur Bearbeitung von Arrays. Warum das so ist, versteht kein Mensch, aber unter Umständen ist dies praktisch, wenn man etwas mit Regular Expression im Zusammenhang mit Arrays macht. Die zwei Querbalken / (neudeutsch Slash) sind die Begrenzungen der Regular Expression. Anstelle des Slashs kann sonst was stehen, also z.B.:

$banane="Every beat of my heart brings me further apart.";
$_=$banane;
$test=m!heart!;
print $test;

Das funktioniert genauso gut. Wird die Regular Expression, in diesem konkreten Fall eine Karikatur einer solchen, gefunden, dann gibt der Match Operator 1 zurück, was hier der Fall ist. Nach dem Ausführen des Skriptes steht 1 auf dem Bildschirm. In den meisten Fällen ist es nicht so praktisch, dass der Match Operator auf den $_ geht. In der Regel lenkt man ihn besser um. Das passiert mit dem Binding Operator (~).

der Binding Operator

$banane="Every beat of my heart brings me further apart.";
$test=$banane=~m!heart!;
print $test;

$test ist jetzt wieder 1, weil heart in $banane enthalten ist. Meistens will man aber irgendetwas machen bzw. lassen, wenn die Regular Expression in dem Ausdruck enthalten ist. Dann ist folgendes sinnvoll:

$banane="Every beat of my heart brings me further apart.";
if($banane=~m!heart!)
{
print "Das Wort heart ist in der Zeichenkette enthalten";
}

Alles klar? 1 ist das Äquvalent für true. Die if Bedingung wird ausgeführt, wenn sie true ist. Das ist hier der Fall. Was ist aber, wenn man wissen will, wie oft ein bestimmtes Element in einer Zeichenkette enthalten ist. Dies interessiert brennend in der Bioinformatik, wenn man wissen will, wie oft eine bestimmte Gensequenz in einer Zeichenkette enthalten ist. Das sieht dann so aus:

Optionen: i und g

$banane="Ene dene dippe dene dippe dene dalia ebbe bebbe bem bio bio bio puf";
$test=@test=$banane=~m/ene/g;
print $test;

@test ist jetzt ein Array, der genau so viele Elemente hat, wie in der Zeichenkette ene gefunden wurde. Die Betonung liegt auf ene (Ene zählt erstmal nicht mit). Das werden wir gleich ändern. Die Zuweisung im Skalarkontext an $test hat dann die Anzahl der Elemente. Siehe Funktionen zur Bearbeitung von Arrays. Soll ene gefunden werden, unabhängig von Groß-/ Kleinschreibung, dann braucht man neben dem g wie general, das dafür sorgt, dass nach dem ersten Treffer nicht gestoppt wird, noch ein i wie indifferent, das dafür sorgt, dass Groß- und Kleinschreibung keine Rolle mehr spielt.

$banane="Ene dene dippe dene dippe dene dalia ebbe bebbe bem bio bio bio puf";
$test=@test=$banane=~m/ene/gi;
print $test;

Oben wirft die Variable $test den wert 3 aus, unten den Wert 4, weil das erste Ene noch dazugekommen ist.
Manchmal ist es interessant in Erfahrung zu bringen, was vor oder nach der Zeichenkette kommt, die gefunden worden ist. Ein Beispiel hierzu unter Suchmaschine in festen Ordnern. Dies geht in einem einfachen Beispiel so.

Die mit Regular Expression übereinstimmenden Textteile abfangen: $1

$banane='Zu welcher Domain gehört eigentlich die email Adresse Andres_Ehmann@web.de';
$banane=~m/@(......)/;
print $1;

Die Punkte stehen für x-beliebige Zeichen (Buchstaben, Hyroglyphen (§$%& etc.), Zahlen usw. Wir haben in diesem Beispiel sechs Punkte(web.de). (In der Praxis ist es komplizierter, wir kommen darauf gleich zurück, weil wir in der Regel nicht genau wissen, nach wievielen Zeichen wir suchen). Entscheidend ist, dass die Punkte in runden Klammern stehen. Was hier steht wird in der Sondervariablen $1 abgespeichert (bei zwei Klammern in $2 etc). Wir erhalten also in diesem Fall für $1 den Wert web.de.
(Nebenbemerkung: In diesem Fall muss die Zeichenkette in einfachen Anführungsstrichen stehen. Hier werden Variablen nicht interpretiert. Sonst sucht Perl nach einem Array Namen @web, den wir aber nicht haben. In einfachen Anführungsstrichen ist das @ Zeichen ein @ Zeichen und kein Array. Das ist hier beabsichtigt.
Alternative: Über den Escape Operator das @ Zeichen abklemmen, also \@.)
Bleiben zwei Probleme:
1. es ist nicht bekannt wie viele Zeichen die Domain hat
2. man will viele Domains nach diesem Schema auslesen.
Fangen wir mit dem ersten Problem an. Die Lösung sieht so aus:

Angeben wie oft ein Zeichen vorkommen soll: + und *

$banane='Zu welcher Domain gehört eigentlich die email Adresse Andres_Ehmann@web.de';
$banane=~m/@(.+)/;
print $1;

Hier ist das Ergebnis web.de und zwar völlig unabhängig davon, wie viele Zeichen die Domain hat. Der Punkt steht hier für jedes x-beliebige Zeichen und davon mindestens eins oder beliebig viele(+). Bei the way, würde man statt des + Zeichens einen * setzen, bedeutet das für das für das unmittelbar davor stehende Zeichen, dass es beliebig oft oder Null mal vorkommen muss. Schwierig wird es, wenn es nach der Domain noch weiter geht, wenn wir also etwas in der Art haben.

$banane='Zu welcher Domain gehört eigentlich die email Adresse Andres_Ehmann@web.de.
Ich bin der Konfliktstoff. Noch schlimmer wird es bei mehreren Punkten';
$banane=~m/@(.+)/;
print $1;

Hier funktioniert es leider nicht mehr. Das Ergebnis ist jetzt  web.de. Ich bin der Konfliktstoff. Noch schlimmer wird es bei mehreren Punkten Dies ist logisch. Jedes x-beliebige Zeichen und davon x-beliebig viele. Es stellt sich also die Frage, wie man die Regular Expression so formuliert, dass sie nach web.de anählt. Man kann erstmal eine Grenze angeben, bis zu der die Regular Expression laufen soll z.B.:

+ und * sind im Default greedy

$banane='Zu welcher Domain gehört eigentlich die email Adresse Andres_Ehmann@web.de.
Ich bin der Konfliktstoff. Noch schlimmer wird es bei mehreren Punkten';
$banane=~m/@(.+)\./;
print $1;

Das Ergebnis ist hier ein Anhalten nach dem letzten Punkt   web.de. Ich bin der Konfliktstoff. Der Punkt muss escaped werden, da er ja selber eine Bedeutung hat (x-beliebiges Zeichen). Wir sehen also, dass das + wie auch das * Zeichen durchgreift, bis zu der Stelle, wo das darauffolgende Zeichen zuletzt auftaucht. Das + Zeichen wie auch das * Zeichen sind also greedy (gierig). Sie stoppen nicht vor dem nächsten übereinstimmenden Zeichen, sondern vor dem letzten. In unserem Beispiel ist das aber nicht das, was wir wollen. Eine ganz entscheidende Bedeutung erlangt jetzt das Fragezeichen - Beispiel:

Umstellen auf nicht greedy: ?

$banane='Zu welcher Domain gehört eigentlich die email Adresse Andres_Ehmann@web.de.
Ich bin der Konfliktstoff. Noch schlimmer wird es bei mehreren Punkten';
$banane=~m/@(.+?)\./;
print $1;

Dies ist leider zuviel des Guten. Hier kommt es zu einem Stopp vor dem ersten Punkt, also nach web.. Wir müssen also die anderen zwei Zeichen dazugeben. Das sieht dann so aus:

$banane='Zu welcher Domain gehört eigentlich die email Adresse Andres_Ehmann@web.de.
Ich bin der Konfliktstoff. Noch schlimmer wird es bei mehreren Punkten';
$banane=~m/@(.+?\.\w+?)\b/;
print $1;

Allmählich wird die Sache schwierig, da diese Regular Expression nicht alle Domains abdeckt. Also step by step. Was steht jetzt in der Regular Expression? Suche ein @ Zeichen! Nach dem @ Zeichen soll irgend ein beliebiges Zeichen folgen, davon mindesten eins (+) oder beliebig viele. Der + Operator soll nicht greedy sein, das heißt, er soll nicht durchmarschieren bis zum letzten Punkt, sondern nur bis zum nächsten Punkt. Danach soll irgendein Wordelement kommen (\w). Von diesen Elementen wiederum soll es mindesten eines geben oder beliebig viele. Stoppen soll er vor der nächsten word boundary (\b). Das Ergebnis ist  web.de. Alles in den runden Klammern wird in der Sondervariablen $1 abgespeichert.

Was ist eigentlich ein Wordelement(\w)?


Als Wordelement zählen keine Umlaute kein ß, keine spanisches n mit tilde, kein französisches s mit ceguille, kein Punkt, etc.. Um es ganz klar zu machen:
\w ist abcdefghijklmnopqrstuvwxyz (groß und klein) 1234567890 und _ mehr nicht. Dies sei hier deutlich gesagt, weil es manchmal auch in der Literatur falsch steht.
Für die Ungläubigen unter uns, ein Beispiel. Man kann damit rumspielen und sich von der Richtigkeit des oben Gesagten überzeugen.

$banane='testXtest';
$banane=~m/(test\wtest)/;
print $1;

Funktioniert! X ist ein ein Wordelement. $1 ist testXtest

$banane='test_test';
$banane=~m/(test\wtest)/;
print $1;

_ ist ein ein Wordelement. $1 ist test_test

$banane='test4test';
$banane=~m/(test\wtest)/;
print $1;

4 ist ein ein Wordelement. $1 ist test4test

$banane='testätest';
$banane=~m/(test\wtest)/;
print $1;

Funktioniert nicht! ä ist kein ein Wordelement. $1 ist undef. (auf dem Schirm leer)

$banane='test.test';
$banane=~m/(test\wtest)/;
print $1;

der Punkt . ist kein ein Wordelement. $1 ist undef. (auf dem Schirm leer)

Bevor ein Überblick gegeben wird, über Regular Expressions, noch ein paar Beispiele, damit das Prinzip klar wird. Nehmen wir mal an, dass man eine Anwendung hat, bei der der User eine Telefonnummer eingeben kann. Die soll folgendes Format haben. 030-47301388. Also Vorwahl, dann Bindestrich, dann Nummer. Buchstaben dürfen also keine vorkommen. Wie prüft man das mit einer Regular Expression. Die Lösung sieht so aus:

Kurzschreibweise für irgendeine Zahl: \d anstatt [0-9]

$banane='030-47301388';
$banane=~m/(\d+-\d+)/;
print $1;

Zur Abwechslung haben wir jetzt \d, wobei \d für Zahlen steht. Wir suchen also einen Texttyp, der zuerst mal ein paar Zahlen hat (mindesten eine oder beliebig viele), dann soll ein Bindestrich kommen, dann wieder eine Portion Zahlen. Bei dieser Variante dürfen also keine Buchstaben vorkommen. Das können wir verbessern. Vorwahlen haben in Deutschland mindestens 3 und höchstens 5 Ziffern. Man kann also erzwingen, dass zuerst 3 bis 5 Zahlen stehen, dann der Bindestrich und dann die eigentliche Nummer.

$banane='030-47301388';
$banane=~m/(\d{3,5}-\d+)/;
print $1;

Man beachte die geschweiften Klammern ({3,5}). Das bedeutet, das Zeichen \d (also eine Zahl) muss mindestens 3 mal und darf höchstens 5 mal auftauchen. Obiges Beispiel liefert ein korrektes Ergebnis.
Im folgenden Beispiel tauchen vor dem Bindestrich nur zwei Zahlen auf. Das heißt ({3,5}) trifft nicht zu.

Präzise angeben, wie oft ein Zeichen vorkommen soll: {mindestens,höchstens}

$banane='03-47301388';
$banane=~m/(\d{3,5}-\d+)/;
print $1;

Jetzt schauen wir uns im nächsten Beispiel Gruppen an.

Gruppen bilden: [das Zeichen | oder jenes | oder dieses]

$banane='ene';
$banane=~m/([ead])/;
print $1;

Ist das ein Treffer oder nicht? Es ist ein Treffer. Die eckige Klammer ändert alles. Nicht ead soll gefunden werden, sondern entweder e, a oder d. In ene ist das e enthalten. Wir erhalten e als Ergebnis. Die eckigen Klammern begegnen uns gleich wieder.
Im den nächsten drei Beispielen wollen wir erzwingen, dass die Regular Expression am Anfang der Zeichenkette steht.

$banane='ene dene dippe denne dippe denne dalia ebbe bebbe bem bio bio bio puff';
$banane=~m/(denne)/;
print $1; 

Funktioniert ist klar, denne ist enthalten.

Anker setzen: ^ und $

$banane='ene dene dippe denne dippe denne dalia ebbe bebbe bem bio bio bio puff';
$banane=~m/^(denne)/;
print $1;

Hier wird die Regular Expression nicht erkannt, weil das ^ Zeichen erzwingt, dass die Regular Expression am Anfang steht.

$banane='ene dene dippe denne dippe denne dalia ebbe bebbe bem bio bio bio puff';
$banane=~m/^(ene)/;
print $1;

Hier wird die Regular Expression erkannt, da ene am Anfang steht.
Das Dach ^ innerhalb der eckigen Klammern hat eine ganz andere Bedeutung hat als außerhalb. Beispiel:

Den Inhalt der eckigen Klammer negieren: ^

$zahlen="12345";
$zahlen=~m/([^\d])/;
print $1;

Hat $1 einen Wert oder hat es keinen? Es hat keinen, weil das ^ hier den Inhalt negiert. Gesucht wird also nicht nach Zahlen, sondern nach dem genauen Gegenteil, das heißt alles, aber keine Zahl.

$zahlen="ft$§ttt";
$zahlen=~m/([^\d])/;
print $1;

Mit den eckigen Klammern kann man wie schon erwähnt Gruppen bilden, z. B. [abc] oder [a-c] oder [$§&] etc. etc.. Einige Gruppen hatten wir schon. \d ist [1234567890] bzw.in Kurzschreibweise [0-9] und \w ist [a-zA-Z_1234567890] .
Mit dem ^ erzwingt man, dass die Regular Expression am Anfang steht, mit dem $ Zeichen, dass sie am Ende steht.

$banane='ene dene dippe denne dippe denne dalia ebbe bebbe bem bio bio bio puff';
$banane=~m/(ene)$/;
print $1;

Hier zeigt $1 nichts, da ene nicht am Ende steht.

$banane='ene dene dippe denne dippe denne dalia ebbe bebbe bem bio bio bio puff';
$banane=~m/(puff)$/;
print $1;

Hier steht puff steht am Ende. Das heißt $1 ist puff.

Was haben wir gelernt?
Klar ist, was \d und \w, ist, was die eckigen, die geschweiften und die runden Klammern bedeuten.
Was man mit i und g erreicht. Was der Binding Operator bewirkt. $1, ^ und $. $_ kennen wir auch. Wir wissen auch, dass es eine Möglichkeit gibt, alle Zeichenketten rauszufischen, die im Hinblick auf ihre Struktur mit der Regular Expression identisch sind.

So ziemlich auf jeder zweiten Website gibt es ein Gästebuch, einen Newsletter, ein Forum oder ein Kontaktformular. Man kann mit einer Regular Expression prüfen, ob die Eingabe der Email-Adresse zumindest syntaktisch richtig ist. Beispiel:

Praktisches Beispiel: Prüfen ob es sich um eine email Adresse handelt

$email='infos@infos24.de';
$test=$email=~m!^\w[\w|\.\-]+@\w[\w\.\-]+\.[a-zA-Z]{2,4}$!;
print $test;

Zuerst sollten wir uns klarmachen, wie eine Email-Adresse aufgebaut ist.
Vor dem @ Zeichen steht zumindest ein Element, das ein \w Zeichen ist. (Wir gehen mal davon aus, dass es keine Email-Adresse gibt, die mit Punkt oder Unterstrich anfängt). Danach kommen beliebig viele Zeichen (\w Zeichen, Punkt oder Bindestrich, keine Leerzeichen und auch keine Hyroglyphen wie $%&/ etc. !).
Dann kommt das @ Zeichen, danach die Domain. Auch die kann beliebig viele \w, Punkte oder Bindestriche haben. Irgendwann kommt aber der Punkt vor der Top Level Domain (com, info, net, org, de, fr, etc.).
Diese hat mindestens zwei (z.B. de) und höchstens vier (info) Zeichen. Hier sind nur noch Buchstaben möglich.
Das Dach ^ am Anfang und das $ Zeichen am Ende brauchen wir, um zu verhindern, dass jemand irgendetwas eingibt. Wir wollen, dass nur eine gültige Email-Adressen eingegeben werden.
Die oben dargestellte Struktur einer Email-Adresse wird von einer Regular Expression abgebildet. Wir haben irgendein Zeichen \w. Dann kommt entweder ein \w Zeichen, ein Punkt oder ein Bindestrich. Davon soll es mindestens eines geben oder beliebig viele. Anschließend kommt das @ Zeichen. Danach muss mindestens ein \w Zeichen kommen, dann entweder ein \w Zeichen, ein Punkt oder ein Bindestrich, im Anschluss ein Punkt. Nach dem Punkt dürfen nur noch Buchstaben kommen und davon mindestens zwei und höchstens vier. $test ist also 1, wenn die Email-Adresse gültig ist.
Einfach mal ausprobieren!

Praktisches Beispiel: Den Namen eines Bildes ermitteln

Ein anderes Problem, welches in der Internet Programmierung häufig auftritt: Unter Gästebuch mit Bildupload stoßen wir auf das Problem, dass wir den gesamten Pfad zu einer Datei haben, wir aber eigentlich nur den Namen der Datei wollen (z.B. c:\Eigene Dateien\Bilder\Berlin\telespargel.jpg - telespargel.de)
Dies ist mit einer Regular Expression leicht zu verwirklichen.

$pfad="c:/Eigene Dateien/Bilder/Berlin/telespargel.jpg";
$pfad=~m!.*/(.*)!;
print $1;

$1 ist in diesem Fall der Name der Datei (telespargel.jpg). Der Punkt steht für ein x-beliebiges Zeichen, dieses wiederum soll null mal oder beliebig oft auftauchen. Es soll hier greedy sein, das heißt der Stern greift nicht durch bis zum ersten Slash sondern bis zum letzten. Was danach kommt, wollen wir haben, folglich klammern wir es, so dass es in der Sondervariablen $1 gespeichert wird.

Regular Expressions in Verbindung mit substitution, split und grep

Bis jetzt haben wir Regular Expression nur in Verbindung mit dem Match Operator kennengelernt. Sie können aber auch mit der Split-, der Grep Funktion sowie dem Substitution Operator genutzt werden. Das schauen wir uns jetzt mal genauer an. Ein praktisches Beispiel ist das Eliminieren von Html Tags. Bei Gästebüchern, Foren, Anzeigenmärkten, Auktionen, Chats, etc. ist es nicht beabsichtigt, dass der User Html Tags eingeben kann. (Öffnet er z.B. einen Table und schließt ihn nicht mehr, besteht die Möglichkeit, dass die ganze Anwendung zerschmettert wird.)
Wie Html Tags eliminiert werden, zeigt das folgende Beispiel.

Praktisches Beispiel: HTML Tags eliminieren


$html="<html><head><title>test</test></head><body>Das ist das, was übrigbleiben soll</body></html>";
$html=~s/<.*?>/ /g;
print $html;

Das Ergebnis ist dann:
test Das ist das,was übrgbleiben soll

Der Substitution Operator hat diese Form:
s/was_ersetzt_werden_soll/durch_was_es_ersetzt_werden_soll/optionen(g, i, etc.). Den Binding Operator kennen wir schon vom Match Operator. Er lenkt den Operator von der Default Variable $_ auf die Variable vor dem Gleichheitszeichen. Das, was ersetzt werden soll, ist in diesem Fall eine Regular Expression.
Interessant ist hier das ?, welches von greedy auf nicht greedy umstellt. Wäre der Stern greedy, würde er durchgreifen bis bis zum letzten >. Das heißt, $html wäre nach der Operation einfach leer. Ersetzt werden soll ist in diesem Beispiel einfach durch ein Leerzeichen. (Jeder Html Tag wird durch ein Leerzeichen ersetzt.)

Praktisches Beispiel: Links in den image tag einbinden

Noch ein Beispiel aus der Praxis. Nehmen wir mal an, wir programmieren einen Chat. In diesen sollen die User Hyperlinks zu Bildern eingeben können (z.B http://www.banane.de/banane.jpg.) Dies soll dann als Bild erscheinen, muss also folglich zu

<img src=http://www.banane.de/banane.jpg>

umgebaut werden. Die User sollen beliebig viele Bilder einbauen können.
Die Lösung für dieses Problem sieht dann so aus:

$html="dies ist ein bild http://www.banane.de/bilder/banane.jpg
und das ist noch eines http://www.tam-tam.de/bilder/ich.jpg ,
wir haben sogar ein drittes nämlich http://www.tingeltangel.de/toll/wessnich.gif
und auch eines das den header weglässt also www.yahoo.de/bilder/test.png";
$html=~s/((http:\/\/|www).*?\.(jpg|gif|png))\b/<img src=..\/..\/perl\/handbuch\/$2>/g;
print $html;

Als Ergebnis erhalten wir

C:\testordner>perl testo.pl
dies ist ein bild <img src=../../perl/handbuch/http://>
und das ist noch eines <img src=../../perl/handbuch/http://> ,
wir haben sogar ein drittes nõmlich <img src=../../perl/handbuch/http://>
und auch eines das den header weglõsst also <img src=../../perl/handbuch/www>
C:\testordner>

Dieser Ausdruck hat jetzt ein paar Neuheiten. Das Slash Zeichen muss escaped werden, weil es sonst einen Kleinkrieg mit der Begrenzung der Regular Expression führt. Neu ist der Balken | innerhalb (jpg|gif|png). Bilder können im Internet nur auf jpg, png oder gif enden. Folglich muss man erzwingen, dass die gesuchte Z eichenkette, der virtuelle Pfad zu dem Bild, entweder auf jpg, gif oder png endet. (| der Balken ist innerhalb einer Regular Expression das Zeichen für oder).
Manche User schreiben anstelle http:// gleich www . Also muss die Zeichenkette, die für den virtuellen Pfad zu dem Bild steht, entweder mit http:// oder mit www beginnen.
Diese Regular Expression hat noch eine weitere interessanten Geschichte. Die virtuellen Pfade zu den Bildern werden einer nach dem anderen rausgefischt und in $2 abgespeichert. (Option g ist eingeschaltet) $2 wiederum wird dann verwendet um den entsprechenden Html Tag zusammenzubauen.

Praktisches Beispiel: Mit grep und Regular Expression bestimmte Elemente eines Arrays finden

Wie oben bereits erwähnt, können Reguar Expressions auch mit grep verwendet werden. Mit grep kann man sich aus einem Array bestimmte Elemente mit bestimmten Eigenschaften rausfischen und an einen Array übergeben.
Ein Beispiel sagt mehr als tausend Worte.

@orginal=("Andres Ehmann","Maria Martínez","Shokufeh Mahmoodzadeh","Werner Binsengrün");
@gefischt=grep(/en|an/,@orginal);
print @gefischt;

Das setzt dann Andres Ehmann auf den Schirm, weil das an enthalten ist, und Werner Binsengrün (en).
Nützlich ist dies, wenn man z. B. aus einem Array mit Email-Adressen diejenigen rausfischen will, die die Domain de haben.

@orginal=("Andres_Ehmann@web.de","heiner@snafu.de","infos@siemens-ag.com",
"info@powernet.uk","schulungen@infso24.de");
@gefischt=grep(/.*\.de/,@orginal);
print @gefischt;

Dieser Ausdruck liefert dann Andres_Ehmann@web.de, heiner@snafu.de und schulungen@infos24.de. Thats what we want.

Wir hatten bei Funktionen zur Bearbeitung von Zeichenketten  den Split Operator kennen gelernt, der eine Zeichenkette an einem Delimiter trennt und in einen Array einliest. Das mag theoretisch erscheinen, aber es sind Fälle denkbar, bei denen der Delimiter (das Zeichen, welches einen Teil vom anderen trennt) nicht genau bekannt ist. In der Bioinformatik z.B. beabsichtigt man aus einem DNA Strang die einzelnen Gene rauszufischen. Das eine Gen ist aber vom anderen unter Umständen durch die gleichen Basenpaare getrennt. Was machen wir jetzt? Richtig! Ein Beispiel:

$banane="Apfel und Birnen oder Kirschen und Pampelmusen oder Himbeeren und Kiwis oder Mangos";
@bananen=split(/und|oder/,$banane);
foreach $himbeere(@bananen)
{
print "$himbeere \n";
}

Da kommt dann Apfel Birnen Kirschen Pampelmusen Himbeeren Kiwis Mangos raus, weil und bzw. oder als Delimiter erkannt wird.

Überraschend ist, dass mit der Funktion glob Regular Expressions nicht funktionieren. Mit einer Kombination aus readdir und grep können wesentlich komplexere Problemen gelöst werden
(siehe  Arbeiten mit Verzeichnissen)

glob kennt nur das joker Zeichen:

chdir("c:/sambar/docs");
@kirsche=(glob("*.htm"));
print @kirsche;

Hier funktioniert glob nicht mehr

chdir("c:/sambar/docs");
@kirsche=(glob("*.htm|html"));
print @kirsche;

Zusammenfassung

-->

Alles noch im Kopf? Ansonsten einfach nochmal die Beispiele ansehen.
/
Begrenzung der Regular Expressions
\
Maskierung
$
die Regular Expression wird nur gefunden, wenn sie am Ende des Bereichs steht
^
die Regular Expression wird nur gefunden, wenn sie am Anfang des Bereichs steht
|
hält alternative Ausdrücke auseinander
i
Groß- /Kleinschreibung wird ignoriert (indifferent)
g
alle Vorkommen suchen (general)
\w
ein Wordelement [a-zA-Z _ 1234567890]
\W
kein Wordelement
\d
eine Ziffer [1234567890]
\D
keine Ziffer
\b
mit /b nach einer Regular Expression wird diese nur gefunden, wenn ein Wort damit endet.
\b
mit /b vor einer Regular Expression wird diese nur gefunden, wenn ein Wort damit anfängt.
+
eine oder mehrere Wiederholungen des Zeichens, das vor dem Pluszeichen steht
*
keine, eine oder mehrere Wiederholungen des Zeichens, das vor dem Sternzeichen steht
?
kein oder einmaliges Vorkommen des davorstehenden Zeichens.
( ) $1
Speichern des Inhaltes der runden Klammern in die Sondervariable $1
[ ead]
e, a oder d
{ 2,5}
mindestens 2 maximal 5
[^ ]
das Dach in der eckigen klammer negiert den Inhalt
m
der Match Operator geht im Default auf die Sondervariable $_
~
der Binding Operator lenkt den Operator von der Default Variable $_ auf die Variable vor dem Gleichheitszeichen.
s
der Substitution Operator hat die Form s/was_ersetzt_werden_soll/durch_was_es_ersetzt_werden_soll/
split
trennt eine Zeichenkette an einem Delimiter und liest diese in einen Array ein
grep
fischt aus einem Array bestimmte Elemente mit bestimmten Eigenschaften heraus und übergibt diese an einen Array

vorhergehendes Kapitel