Artikel im Internet unter http://www.hidemail.de/blog/regulaere-ausdruecke-2.shtml.
Freitag, 2.2.2007, 11:26:13 Uhr

Reguläre Ausdrücke - Einfaches Suchen die 2.


Die Grundlagen des Suchens wurde bereits hier vorgestellt.Es wurde vorgestellt, wie man Zeichenketten in Zeichenketten finden kann. Jedoch war das ganze noch ziemlich "unhandlich" und sehr umständlich.
Was zum Beispiel, wenn man zum Beispiel die Groß-Kleinschreibung ignorieren möchte, oder ganze Bereiche von bestimmten Zeichen suchen oder ausschließen möchte?

Also, weiter gehts mit dem "einfachen" Suchen

Reguläre Ausdrücke werden wesentlich flexibler durch Flags, die angehängt werden können.

Flags hinter regulären Ausdrücken

Hinter dem letzten Begrenzerzeichen (normalerweise der Schrägstrich) eines regulären Ausdrucks kann noch ein oder mehrere Buchstaben, die Flags eben, angegeben werden.
Das Verhalten des RedEx (so werden Reguläre Ausdrücke in Kurzform genannt) wird dadurch beeinflußt bzw. erweitert.

Hier sind alle Flags
c Bei einem auftretenden Fehler nicht die Suchposition zurücksetzen.
g Global suchen, d.h. alle Vorkommen finden.
i Groß-/Kleinschreibung ignorieren
m Zeichenketten können aus mehreren Zeilen bestehen
o Suchmuster nur einmal anwenden
s Zeichenketten als eine einzige Zeile betrachten
x Erweiterte Syntax verwenden
e Ersetzen-Teil erst evaluieren, dann ersetzen


Flags können beliebig kombiniert werden, aber dazu später.

Groß-Kleinschreibung ignorieren
Interessant ist im Moment für uns das Flag i. i ignoriert die Groß-Kleinschreibung wie man im folgendem Beispiel sehen kann:

$t="test";

if ($t=~ /Test/i){print "wahr";}


Ausgabe: wahr

Test findet also auch test, ebenso würde TeSt oder TEST zutreffen. Das Flag i ist sehr wichtig und wird entsprechend oft verwendet.

Aber wie es immer so ist, es gibt da auch Ausnahmen.

$t="Männer";

if ($t=~ /MÄNNER/i){print "wahr";} else {print "falsch";}


Ausgabe: falsch

Was ist passiert? Nun, man kann es sich denken: Perl denkt "englisch", ist also für den englischen Zeichensatz konzipiert. Und kann deswegen mit allen Umlauten, die die Engländer und Amerikaner nicht kennen, nicht umgehen.
Das Ä wird also NICHT automatisch in ein ä verwandelt und wird deswegen NICHT erkannt!

Wie man das Problem lösen kann beschreibe ich später, oder genauer gesagt, im nächsten Kapitel.

Zeichenklassen in Regulären Ausdrücken
Was will er jetzt mit Zeichenklassen, kann man fragen, aber nur Gedult!

Also: Zeichenklassen. Zeichenklassen in Perl geben, wie der name schon sagt, Klassen von Zeichen an. Das können Buchstaben, Ziffern und Sonderzeichen sein.

Beispielsweise definiert ein [a-z] alle Kleinbuchstaben, allerdings ohne Umlaute. [0-9] definiert alle Ziffern und ein \W gilt für alle Zeichen, die kein Buchstabe, Ziffer oder Unterstrich _ sind. Und weil Perl ja so gut ist, kann man eigene Zeichenklassen definieren. Geht ganz einfach:
[äöüÄÖÜß] definiert alle deutschspachigen Umlaute! Für den Regulären Ausdruck ist übrigens immer nur EIN Zeichen relevant.

So, und jetzt kommen wir wieder zu unserem Beispiel von oben:

$t="Männer";
if ($t=~ /m[äÄ]NNER/i){print "wahr";}


Ausgabe: wahr

Erklärung:
Verglichen wird zuerst das m, das zutrifft, danach das ä oder das Ä, was dann ja auch passt, und zum Schluß der Rest.
Zugegeben, ein noch etwas unbrauchbares Beispiel, aber immerhin ist das Grundprinzip schon mal da.

Anderes Beispiel für Zeichenklassen

$t="Willkommen in Perl 5";

if ($t=~ /[0-9]/){print "wahr. Gefunden wurde $&";}



Ausgabe:
wahr. Gefunden wurde 5

Wenn also nur ein Zeichen der Zeichenklasse, in diesem Fall die 5, in $t enthalten ist, wird ein wahr ausgegeben.

Übrigens
Die Variable $& enthält immer das zu Letzt gefundene Muster, wie in diesem Fall die 5.

Zeichenklassen ausschließen
Hier ein Beispiel dafür, wie man einzelne Zeichenklassen ausschließen kann.
Angenommen, man möchte ausschließen, daß sich Buchstaben oder Sonderzeichen im Skalar befinden, oder andersherum gesagt, es dürfen nur Ziffern enthalten sein:

$t="Willkommen in Perl 5";

if ($t=~ /[^0-9]/){print "Alarm. Gefunden wurde $&";}



Ausgabe:
Alarm. Gefunden wurde W

Was ist passiert?
Definiert wird die Zeichenklasse [0-9], also alle Ziffern. Zusätzlich sehen Sie aber das ^-Zeichen vor der 0-9. Das bedeutet eine Umkehrung, oder Negation.
Es wird also gesucht nach zeichen, die NICHT 0-9 sind, also alle Sonderzeichen und Buchstaben. Logisch, daß dann gleich das W gefunden wird.

Für einige oft verwendete Zeichenklassen gibt es abkürzende Schreibweisen:

\d = [0-9] alle Ziffern
\D = [^0-9] Gegenstück zu \d
\w = [a-zA-Z_0-9] Buchstabe, Unterstrich oder Ziffer
\W = [^a-zA-Z_0-9] Gegenstück zu \w
\s = [ \t\n\f\r] Leerzeichen, Tabulatoren, Zeilenumbruch usw.
\S = [^ \t\n\f\r] Gegenstück zu \s


Das Letzte beispiel könnte also auch folgendermaßen geschrieben werden:

$t="Willkommen in Perl 5";

if ($t=~ /[^\d]/){print "Alarm. Gefunden wurde $&";}



Wichtig:
Die eckigen Klammern müssen in diesem Fall bestehen bleiben, da ohne die Klammern der Ausdruck lauten würde: Suche am Wortanfang nach einer Ziffer, also ganz was anderes als gewünscht!
Siehe hier
So, erstmal wieder genug davon. Demnächst gehts weiter.


Artikel im Internet unter http://www.hidemail.de/blog/regulaere-ausdruecke-2.shtml.