Mehr zur Zeichensuche
Optionen beim Suchoperator
Das Verhalten bei der Suche kann durch nachgestellte Optionen beeinflußt
werden:
-
g
("global")
Während standardmäßig die Suche beim ersten Treffer
abgebrochen wird, veranlaßt diese Option die Ausgabe einer
Liste von Lösungen, so als würde man die Stelle nach einem
gefundenen Substring als Startpunkt für eine erneute Suche
verwenden.
Beispiel:
#!/usr/local/bin/perl -w
use strict;
my $t = "123-456-789";
my @a = ($t =~ /[1-9]{3}/g); # Suche nach Zifferntripel foreach my $x (@a) { print "$x " } print "\n";
foreach my $x ($t =~ /[1-9]{3}/g) { print "$x " } print "\n";
while($t =~ /[1-9]{3}/g) { print "$& " } print "\n";
|
|
123 456 789 123 456 789 123 456 789
|
|
Der erste Teil zeigt, wie die Suchoperation eine Liste aller
gefundenen Substrings zurückgibt. Anstelle der Zuweisung zu
einem Array kann auch foreach
direkt die Lösungsliste
durchlaufen. Sehr häufig verwendet man auch die dritte dargestellte
Methode: schrittweises Durchsuchen der Zeichenkette mittels einer
while
-Schleife.
Es ist zu beachten, daß die Suche nach einer weiteren Lösung
jeweils hinter dem zuvor gefundenen Muster beginnt. Daher gibt folgendes
Skript nur die eine Lösung "-ab-
" aus (und
nicht noch "-cd-
" zusätzlich).
#!/usr/local/bin/perl -w
use strict;
my $t = "-ab-cd-";
foreach($t =~ /-[a-z][a-z]-/g) { print "$_ " }
|
|
-
i
("case-insensitive")
Verwendet man diese Option, wird bei der Suche nach Buchstaben nicht
zwischen Groß- und Kleinschreibung unterschieden (dies funktioniert
auch bei nationalen Sonderzeichen wie den deutschen Umlauten sofern das
Betriebssystem die entsprechende Sprachumgebung unterstützt).
Beispiel:
#!/usr/local/bin/perl -w
use strict;
my $t = "Ähnlichkeit";
if($t =~ /ähn/) { print "wahr\n" } else { print "falsch\n" } if($t =~ /ähn/i) { print "wahr\n" } else { print "falsch\n" }
|
|
-
s
("single line")
Hiermit wird eine Zeichenkette als einzelne Zeile betrachtet, auch
wenn sie Zeilenvorschübe ("\n
") enthält.
Dadurch entfällt dann in einem Suchmuster die Sonderrolle
von "\n
" bezüglich des Punktes
(".
"), der sonst nur auf alle anderen Zeichen,
nicht aber den Zeilenvorschub, paßt.
Beispiel:
#!/usr/local/bin/perl -w
use strict;
my $t = "AAA\nBBB\n";
if($t =~ /A.B/) { print "wahr\n" } else { print "falsch\n" } if($t =~ /A.B/s) { print "wahr\n" } else { print "falsch\n" }
|
|
-
m
("multiple lines")
Verwendet man diese Option, so passen die Ankerpunkte
"^
" und "$
" nicht nur am
Anfang bzw. Ende der vorgegebenen Zeichenkette,
sondern auch an jedem Zeilenanfang und -ende. Um einen Ankerpunkt an
den Anfang oder das Ende des untersuchten Strings zu setzen, muß
in diesem Falle "\A
" bzw. "\Z
"
verwendet werden.
Beispiel:
#!/usr/local/bin/perl -w
use strict;
my $t = "Kugel 1\nPyramide 2\nQuader 3\n";
my @a = ($t =~ /^\w+/g); foreach (@a) { print "1) $_\n" } @a = ($t =~ /^\w+/gm); foreach (@a) { print "2) $_\n" }
|
|
1) Kugel 2) Kugel 2) Pyramide 2) Quader
|
|
-
o
("compile once")
Diese Option dient der Optimierung der Mustersuche (hinsichtlich der
Geschwindigkeit) und sollte nur verwendet werden, wenn dies unbedingt
nötig ist. Ihre Wirkung besteht darin, daß eine
Variablenersetzung im Suchmuster nur einmal zu Beginn
stattfindet. Daher muß sichergestellt sein, daß sich
die entsprechenden
Variablen während der Suche nicht ändern.
Beispiel:
#!/usr/local/bin/perl -w
use strict;
my $t = "123..abc...456";
my $muster = '0-9'; while($t =~ /[$muster]+/g) { $muster = 'a-z'; # Zeichenklasse ändern print "1) $&\n"; }
$muster = '0-9'; while($t =~ /[$muster]+/go) { $muster = 'a-z'; # hier wirkungslos print "2) $&\n"; }
|
|
Hier sieht man nebenbei, daß Suchmuster durchaus auch in Variablen
gespeichert werden können.
-
x
("extended")
Um komplizierte reguläre Ausdrücke übersichtlicher
darstellen zu können, gibt es die Option "x
",
die es ermöglicht, Ausdrücke auf mehrere Zeilen zu verteilen
und (normale) Perl-Kommentare einzufügen.
Beispiel:
#!/usr/local/bin/perl -w
use strict;
my $t = '...<IMG SRC="pfad/bild.gif" WIDTH=110>...';
$t =~ /<IMG # HTML-Tag für Bild (Beginn) \s+ # Leerzeichen SRC=" # Hier kommt der URL (.+?) # Diesen Pfad suchen wir " # Ende des URL .*? # vielleicht noch Optionen > # Ende des HTML-Tags /ix; # case-insensitive, extended
print "$1\n";
|
|
[Seitenanfang]
Optionen innerhalb eines regulären Ausdrucks
Die im vorherigen Abschnitt beschriebenen global wirkenden Optionen
können auch innerhalb eines regulären Ausdrucks gesetzt
werden, um beispielsweise nur Teile davon zu beeinflussen.
Dies wird durch
"(?
Option(en))
" bewerkstelligt.
Hierbei können die Optionen i
, m
,
s
und x
verwendet werden. Die Wirkung
erstreckt sich bis zum Ende des regulären Ausdrucks, innerhalb einer
Gruppierung oder bis zu einer Deaktivierung mittels
"(?-
Option(en))
".
#!/usr/local/bin/perl -w
use strict;
my $t = "ABcd";
$t =~ /[a-z][a-z]/i; print "$&\n"; # 1 $t =~ /(?i)[a-z][a-z]/; print "$&\n"; # 2 $t =~ /((?i)[a-z])[a-z]/; print "$&\n"; # 3 $t =~ /[a-z](?i)[a-z]/; print "$&\n"; # 4 $t =~ /(?i)[a-z](?-i)[a-z]/; print "$&\n"; # 5
|
|
Test 2 ist äquivalent zu Test 1. In Test 3 ist wegen der
Klammerung nur für den ersten Buchstaben Großschrift erlaubt.
Da in Test 4 der erste Buchstabe klein geschrieben sein muß,
kommt nur "cd
" als Lösung infrage. Die letzte
Zeile zeigt wie man eine Option wieder abschalten kann (entspricht
Test 3).
[Seitenanfang]
Spezielle Variablen
In den vorherigen Abschnitten wurden schon einige spezielle Perl-Variablen
im Zusammenhang mit der Mustersuche erwähnt; hier eine Übersicht:
-
$&
gibt das gefundene Muster zurück
-
$1,$2,$3,...
enthält das Muster der 1.,2.,3.,...
runden Klammer
-
$+
enthält das Muster der letzten runden Klammer
-
$`
enthält die Zeichenkette, die vor dem gefundenen
Muster steht
-
$'
enthält die Zeichenkette, die hinter dem gefundenen
Muster steht
Beispiel:
#!/usr/local/bin/perl -w
use strict;
my $s = "Dies ist ein Test ...";
if($s =~ /is([a-z]) (.*) Test/) { print $&."\n"; print $1."\n"; print $2."\n"; print $+."\n"; print $`."\n"; print $'."\n"; }
|
|
ist ein Test t ein ein Dies ...
|
|
[Seitenanfang]
Suchen und Ersetzen
Anstelle einer einfachen Suche kann man in Perl auch den gefundenen
Ausdruck direkt durch einen neuen ersetzen.
Allgemein:
$string =~ s/
Regexp/
Ersatz/
Optionen;
Dabei wird wie beim Suchoperator ("m/.../
")
$string
nach
einer zu Regexp passenden Zeichenkette durchsucht. Wird ein solcher
Teilstring gefunden, so wird an dessen Stelle der Text Ersatz gesetzt.
Beispiel:
#!/usr/local/bin/perl -w
use strict;
my $t = "Beispiel"; $t =~ s/e/-e-/; print "$t\n";
|
|
Im obigen Beispiel wird der String $t
nach dem Buchstaben
"e
" abgesucht und (beim ersten Auffinden) durch die
Zeichenkette "-e-
" ersetzt.
Auch beim Suchen und Ersetzen können die Schrägstriche des Operators
durch andere Zeichen ersetzt werden (keine alphanumerischen Symbole oder
Leerzeichen).
Es können die gleichen Optionen wie beim Suchoperator verwendet werden,
ihre Wirkung bezieht sich dabei auf den regulären Ausdruck.
Eine zusätzliche Option ermöglicht die Auswertung
des Ersatz-Teils.
Optionen:
-
g
("global")
(siehe Optionen beim Suchoperator)
-
i
("case-insensitive")
(siehe Optionen beim Suchoperator)
-
s
("single line")
(siehe Optionen beim Suchoperator)
-
m
("multiple lines")
(siehe Optionen beim Suchoperator)
-
o
("compile once")
(siehe Optionen beim Suchoperator)
-
x
("extended")
(siehe Optionen beim Suchoperator)
-
e
("evaluate")
Diese Option bewirkt, daß beim Ersetzen der einzusetzende
Ausdruck wie
ein Befehl in Perl behandelt und ausgewertet wird. Dies kann sogar mehrfach
geschehen.
Beispiel:
#!/usr/local/bin/perl -w
use strict;
my $t = "5+7";
$t =~ s|^(\d+)\+(\d+)$|$1+$2|e; # hier '|' statt '/' print "$t\n\n";
$t = '_x_';
(my $s = $t) =~ s/x+/'"m" x 3' x 1/; print "$s\n";
($s = $t) =~ s/x+/'"m" x 3' x 1/e; print "$s\n";
($s = $t) =~ s/x+/'"m" x 3' x 1/ee; print "$s\n";
|
|
12
_'"m" x 3' x 1_ _"m" x 3_ _mmm_
|
|
[Seitenanfang]