GUI mit Perl/Tk

Tutorial

Ersetzen, Übersetzen in Strings

So wie Perl Muster in Strings erkennen kann, können auch Muster durch Strings ersetzt werden. Dazu verwenden wir die s-Funktion.

Um den Substring london durch London in der Variablen $satz zu ersetzen, verwenden wir die Anweisung:

$satz =~ 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;

Der Rückgabewert des Ausdrucks ist wieder die Anzahl gemachter Ersetzungen. In diesem Fall 0 (false) oder ein Wert größer als 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 Groß- 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

my $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/;

Übersetzen

Die Funktion tr ermöglicht die Übersetzung 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/;

Übung

Das aktuelle Programm zählt die Zeilen, welche einen bestimmten String beinhalten. Ändere 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 heiße countlines.pl. Bei einem Aufruf

countlines.pl 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.

Ändere 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.pl du

unter anderem die folgende Zeile ausgeben:

022Blackcurrant-Büchse (du)rch die Luft, die er mit einem Hechtsprung auf den
Top