Dabei sind Such- und Ersetzungsliste jeweils Listen aus Symbolen. Beim Ersetzen wird wie folgt vorgegangen: tritt in$string =~ tr/
Suchliste/
Ersetzungsliste/
Optionen;
$string
das erste Zeichen der Suchliste
auf, so wird dieses Zeichen entfernt und an die Stelle wird das erste Zeichen der
Ersetzungsliste gesetzt. Analog wird jedes Auftreten des zweiten Zeichens der Suchliste
durch das zweite Zeichen der Ersetzungliste ersetzt usw.
Beispiel:
#!/usr/local/bin/perl -w $a = "--abcd--cde--"; print "$a\n"; $a =~ tr/abc/ABC/; print "$a\n"; |
--abcd--cde-- --ABCd--Cde-- |
Zur Vereinfachung können mittels eines Minuszeichens "-
" auch
Zeichenbereiche angegeben werden (z.B. "alle Kleinbuchstaben" durch "a-z
").
Die Reihenfolge der Zeichen ist dabei durch den ASCII-Code bestimmt. Will man ein Minus
ersetzen, so muß es wegen dieser Sonderbedeutung an Anfang oder Ende von
Such- bzw. Ersetzungliste stehen.
Tritt ein Zeichen mehrmals in der Suchliste auf, so wird es durch dasjenige Symbol der Ersetzungliste ersetzt, das als erstes als Partner auftritt. Ist die Suchliste länger als die Ersetzungsliste, so wird das letzte Zeichen der Ersetzungsliste so oft wiederholt, bis beide Listen gleich lang sind (die überzähligen Symbole der Suchliste werden also alle dem letzten Zeichen der Ersetzungsliste zugeordnet). Ist die Ersetzungsliste leer, so wird der Inhalt der Suchliste dort eingetragen (dadurch finden zwar keine ersichtlichen Ersetzungen statt, aber der Operator kann dann zum Zählen von Zeichen verwendet werden, da der Rückgabewert die Anzahl der ersetzten Zeichen ist).
#!/usr/local/bin/perl -w $a = "--abcd--cde--"; print "$a\n\n"; ($b = $a) =~ tr/a-c/A-C/; # entspricht 'tr/abc/ABC/' print "$b\n"; ($b = $a) =~ tr/ccc/123/; # entspricht 'tr/c/1/' print "$b\n"; ($b = $a) =~ tr/-b/+-/; print "$b\n"; ($b = $a) =~ tr/abcde/xy/; # entspricht 'tr/abcde/xyyyy/' print "$b\n"; $z = ($b = $a) =~ tr/-//; # entspricht 'tr/-/-/' print "$b ($z Minuszeichen in $a)\n"; |
--abcd--cde-- --ABCd--Cde-- --ab1d--1de-- ++a-cd++cde++ --xyyy--yyy-- --abcd--cde-- (6 Minuszeichen in --abcd--cde--) |
Anmerkung zur Zuweisung: Im obigen Beispiel wird jeweils der Variablen $b
zunächst der Inhalt von $a
zugewiesen, anschließend erfolgt dann
die Ersetzung (nur in $b
!). Die vorletzte Zeile zeigt noch, wie man den
Rückgabewert der Ersetzungsoperation erhält.
Optionen:
c
("complement")
Diese Option bedeutet für die Suchliste soviel wie "alle Zeichen außer...". Dabei ist mit "alle Zeichen" der ASCII-Zeichensatz gemeint.
Beispiel:
#!/usr/local/bin/perl -w $a = "abcd?%(1)---23ABCDEF4 xxx5\n"; print "$a\n"; $a =~ tr/0-9/./c; print "$a\n"; |
abcd?(1)---23ABCDEF4 xxx5 ......1....23......4....5. |
Hier werden alle Zeichen, die keine Ziffern sind, durch Punkte ersetzt.
s
("squash down")
Werden aufeinander folgende Zeichen durch das gleiche Symbol ersetzt, so wird bei Verwendung dieser Option dieses Symbol nur einmal gesetzt.
Erweiterung des obigen Beispiels:
#!/usr/local/bin/perl -w $a = "abcd?%(1)---23ABCDEF4 xxx5\n"; print "$a\n"; $a =~ tr/0-9/./cs; print "$a\n"; |
abcd?(1)---23ABCDEF4 xxx5 .1.23.4.5. |
d
("delete")
Diese Option vehindert die Verlängerung der Ersetzungsliste, falls die Suchliste kürzer ist. Dies bewirkt, daß die überzähligen Zeichen der Suchliste gelöscht werden.
Beispiel:
#!/usr/local/bin/perl -w $a = "--abcd--cde--"; print "$a\n\n"; ($b = $a) =~ tr/abcde/xy/; # entspricht 'tr/abcde/xyyyy/' print "$b\n"; ($b = $a) =~ tr/abcde/xy/d; print "$b\n"; |
--abcd--cde-- --xyyy--yyy-- --xy---- |
Anstelle der Schrägstriche können im Ersetzungsoperator auch andere Zeichen
gesetzt werden, wobei Klammern gesondert behandelt werden. Außerdem kann
(in Anlehnung an den Ersetzungsoperator in sed) anstelle von "tr
"
auch "y
" stehen.
Der einfache Suchoperator, der reguläre Ausdrücke verwendet, sieht allgemein so aus:
Hier wird die Zeichenkette in$string =~ m/
regexp/
Optionen;
$string
danach durchsucht, ob sich
der reguläre Ausdruck "regexp" an irgendeiner
Stelle darin anwenden läßt. Der Rückgabewert
ist "wahr" ("true
"), falls dies zutrifft, sonst "falsch"
("false
"). Verwendet man anstelle von
"=~
" den Operator "!~
", so ist der Rückgabewert
genau entgegengesetzt: "true
" bei erfolgloser Suche.
Statt der Schrägstriche ("/.../
") können auch einige
andere Zeichen benutzt werden, sofern es sich dabei nicht um alphanumerische
Symbole (Buchstaben, Ziffern, Unterstrich) oder Leerzeichen (space,
newline, tab,...) handelt; verwendet man Schrägstriche,
kann das "m
" am Anfang weggelassen werden.
Erläuterungen, was reguläre Ausdrücke sind und wie sie verwendet werden, finden sich in diesen Extra-Kapiteln:
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 $t = "123-456-789"; @a = ($t =~ /[1-9]{3}/g); # Suche nach Zifferntripel foreach $x (@a) { print "$x " } print "\n"; foreach $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 $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).
Beispiel:
#!/usr/local/bin/perl -w $t = "Ähnlichkeit"; if($t =~ /ähn/) { print "true\n" } else { print "false\n" } if($t =~ /ähn/i) { print "true\n" } else { print "false\n" } |
false true |
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 $t = "AAA\nBBB\n"; if($t =~ /A.B/) { print "true\n" } else { print "false\n" } if($t =~ /A.B/s) { print "true\n" } else { print "false\n" } |
false true |
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.
Beispiel:
#!/usr/local/bin/perl -w $t = "Kugel 1\nPyramide 2\nQuader 3\n"; @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 (bezüglich 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 $t = "123..abc...456"; $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"; } |
1) 123 1) abc 2) 123 2) 456 |
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 $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"; |
pfad/bild.gif |
$&
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
#!/usr/local/bin/perl -w $a = "Dies ist ein Test ..."; if($a =~ /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 ... |
Dabei wird wie beim Suchoperator ("$string =~ s/
regexp/
Ersatz/
Optionen;
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 $t = "Beispiel"; $t =~ s/e/-e-/; print "$t\n"; |
B-e-ispiel |
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 auch den regulären Ausdruck. Eine zusätzliche Option ermöglicht die Auswertung des Ersatz-Teils.
Optionen:
g
("global")
(siehe Suchoperator)
i
("case-insensitive")
(siehe Suchoperator)
s
("single line")
(siehe Suchoperator)
m
("multiple lines")
(siehe Suchoperator)
o
("compile once")
(siehe Suchoperator)
x
("extended")
(siehe 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 $t = "5+7"; $t =~ s|^(\d+)\+(\d+)$|$1+$2|e; # hier '|' anstelle von '/' print "$t\n\n"; $t = 'Comxxx'; ($s = $t) =~ s/x+/sprintf("sprintf(\"puter\")")/; print "$s\n"; ($s = $t) =~ s/x+/sprintf("sprintf(\"puter\")")/e; print "$s\n"; ($s = $t) =~ s/x+/sprintf("sprintf(\"puter\")")/ee; print "$s\n"; |
12 Comsprintf("sprintf("puter")") Comsprintf("puter") Computer |
Autor: Eike Grote | Letzte Änderung: 18.02.1999 |