Ersetzen,
Uebersetzen in Strings
Sowie Perl Muster in Strings erkennen kann, können auch Muster durch
Strings ersetzt werden. Dazu verwenden wird die s-Funktion,
welche ähnlich wie im vi-Editor oder beim sed aussieht. Wiederum wird
der Vergleichsoperator verwendet, welcher wiederum weggelassen werden
kann, falls die Ersetzung auf der Defaultvariablen $_ gemacht werden
soll.
Um den Substring london durch London in der Variablen $satz zu ersetzen,
verwenden wir die Anweisung
$satz =~ s/london/London/;
Mit der Defaultvariablen $_, sieht das folgendermassen aus
s/london/London/;
Beachte, dass die zwei regulären Ausdrücke (london und London)
insgesamt von drei Schrägstrichen / umgeben sind. Das Resultat dieses Ausdruckes
ist die Anzahl gemachter Ersetzungen. In diesem Fall Null (false) oder Eins (true).
Optionen
Dieses Beispiel ersetzt nur das erste Auftreten von london im String.
Verschiedene Optionen steuern das
Verhalten der s-Funktion. Falls wir alle Vorkommnisse ersetzen
wollen, müssen wir nach dem letzten Schrägstrich ein g anhängen.
s/london/London/g;
Wiederum ist das Resultat dieses Ausdruckes die Anzahl gemachter Ersetzungen. In diesem
Fall Null (false) oder >Null (true).
Falls wir auch Dinge, wie lOndon, lonDON, LoNDoN, ersetzen wollen,
könnte das ganze folgendermassen aussehen:
s/[Ll][Oo][Nn][Dd][Oo][Nn]/London/g
Ein einfacherer Weg ist jedoch die Verwendung der i Option (i wie 'ignore
case'). Der Ausdruck
s/london/London/gi;
macht eine globale Ersetzung ohne Beachtung der Gross- oder Kleinschreibung. Die i
Option kann auch beim normalen Vergleich von Mustern /.../i verwendet
werden.
Muster wiederverwenden
Häufig ist es sinnvoll, die aufgefundenen Muster wiederzuverwenden. Dabei werden die
Muster in Klammern der Reihe nach in die Variablen $1,...,$9
zwischengespeichert. Diese Variablen können sowohl im gleichen regulären Ausdruck, als
auch in der Ersetzung wiederverwendet werden, indem die speziellen Codes für reguläre
Ausdrücke \1,...,\9 angewendet werden. Das Beispiel
$_ = "Lord Whopper of Fibbing";
s/([A-Z])/:$1:/g;
print "$_\n";
ersetzt jeden Grossbuchstaben durch denselben Buchstaben umgeben von zwei
Doppelpunkten. Das heisst, die Ausgabe lautet: :L:ord :W:hopper of :F:ibbing. Die
Variablen $1,...,$9 sind read-only Variabeln; sie können nicht direkt
verändert werden.
Im folgenden Beispiel wird die Testanweisung
if (/(\b.+\b) \1/) {
print "Found $1 repeated\n";
}
jedes wiederholte Wort erkennen. Der Code \b stellt eine Wortbegrenzung dar und .+
erkennt jeden nicht-leeren String. Damit erkennt \b.+\b irgendein String zwischen
Wortbegrenzern. Durch die Klammern wird eine Zwischenspeicherung veranlasst und diese wird
innerhalb des regulären Ausdrucks mit \1, im restlichen Programm mit $1
referenziert.
Der folgende Ausdruck vertauscht den ersten und den letzten Buchstaben einer Zeile in
der $_-Variablen:
s/^(.)(.*)(.)$/$3$2$1/
Der Code ^ erkennt den Anfang, $ das Ende einer Zeile.
$1 speichert den ersten Buchstaben; $2 speichert alles bis
zum letzten Buchstaben, welcher in $3 gespeichert wird. Danach
wird die ganze Zeile ersetzt, indem $1 und $3 vertauscht
werden.
Nach einem Vergleich hat man drei Spezial-Variabeln $`, $& und $'
zur Verfügung, in welchen die Teile vor, während und nach dem Muster abgespeichert sind.
Nach
$_ = "Lord Whopper of Fibbing";
/pp/;
sind die folgenden Aussagen wahr: (Beachte, dass eq die Gleichheit von Strings
bedeutet.)
$` eq "Lord Who";
$& eq "pp";
$' eq "er of Fibbing";
Zum Schluss des Abschnittes über Muster-Wiederverwendung möchten wir noch darauf
aufmerksam machen, dass Variabeln, welche innerhalb der Schrägstriche eines Vergleiches
verwendet werden, interpoliert werden. Damit wird in
$search = "the";
s/$search/xxx/g;
jedes Vorkommen von the durch xxx ersetzt. Falls jedes Vorkommen von there
ersetzt werden soll, kann nicht s/$searchre/xxx/ verwendet werden, da der Versuch
unternommen wird, die Variable $searchre zu interpolieren. Falls hingegen der
Variablenname in geschweifte Klammern gesetzt wird, sieht der richtige Code wie folgt aus:
$search = "the";
s/${search}re/xxx/;
Uebersetzen
Die Funktion tr ermöglicht die Uebersetzung
von einzelnen Buchstaben. Die folgende Anweisung ersetzt in der Variablen
$sentence jedes a mit einem e, jedes b mit einem
d und jedes c mit einem f. Der Ausdruck gibt die
Anzahl gemachter Ersetzungen zurück.
$sentence =~ tr/abc/edf/;
Die meisten der speziellen Codes für reguläre Ausdrücke können in der Funktion tr
nicht verwendet werden. Die folgende Anweisung zum Beispiel, zählt die Anzahl Sterne in
der Variablen $sentence und speichert sie in der $count-Variablen ab.
$count = ($sentence =~ tr/*/*/);
Der Bindestrich jedoch bedeutet immer noch einen Bereich ("zwischen"). Diese
Anweisung übersetzt $_ in Grossbuchstaben:
tr/a-z/A-Z/;
Uebung
Das aktuelle Programm zählt die Zeilen, welche einen bestimmten String beinhalten.
Aendere das Programm so, dass es die Zeilen zählt, welche einen Doppelbuchstaben
enthalten. Diese Doppelbuchstaben sollen in Klammern ausgegeben werden.
Zum Beispiel sollten folgende Zeilen erscheinen:
«30?» Fabio Hi(pp)in steht auf dem Tre(pp)enabsatz und zieht kräftig an Sophies
«Du, sag mal: Hast Du schon a(ll)es gezügelt?»
Ein bisschen interessanter ist vielleicht eine Verallgemeinerung dieses Programmes. Wie
möchten die Suchstrings als Argumente übergeben. Angenommen das Programm heisse countlines.
Bei einem Aufruf
countlines first second etc
werden die Argumente im Array @ARGV abgespeichert. Somit ist $ARGV[0]
gleich first, $ARGV[1] gleich second und $ARGV[2] gleich etc.
Aendere das Programm, sodass es ein Argument akzeptiert und nur diejenigen
Zeilen zählt, welche diesen String enthalten. Setze diese Vorkommnisse in Klammern. Damit
wird
countlines du
unter anderem die folgende Zeile ausgeben:
022Blackcurrant-Büchse (du)rch die Luft, die er mit einem Hechtsprung auf den
 
|