Schneller mit Strings und Zahlen arbeitenPerl

SeitenanfangSeitenendeLänge eines Strings

Die Länge eines Strings kann man ganz einfach mit der Funktion length() bestimmen:

$s="Wieviele Zeichen besitze ich?\n";
print length($s);
30

SeitenanfangSeitenendeAneinanderhängen von Strings

Mir Hilfe von .= kann man einen String an einen anderen anhängen: $string1.=$string2 Wer gewohnt ist $string1=$string1.$string2 zu schreiben, der sollte das besser sein lassen! Perl braucht dazu viel mehr Zeit. Der Grund: .= hängt am Ende des Strings an. Die zweite Methode hängt die beiden Strings zusammen und kopiert das Ergebnis dann in den ersten String. Also ab jetzt immer .= verwenden.

SeitenanfangSeitenendeAufaddieren von Zahlen

Beim +=-Operator spart man ebenfalls Zeit ein - jedoch nicht so viel als im Vergleich zu .=.

SeitenanfangSeitenendeSplit in Vergleich mit regulären Ausdrücken

Der Vergleich von split-Operator mit regulären Ausdrücken liefert verschiedene Aussagen - je Problemstellung.

Will man einen String - nach einem Muster aufteilen, so ist es besser den split-Operator zu benutzen.

@a=split(/\s+/,$string))[3]; # effektiver

@a=$string=~/(\S+)/g;

Will man eine bestimmte Anzahl von Elementen aus dem Anfang des Strings ziehen, so ist dies von der größe des zu durchsuchenden Strings abhängig. Falls der String recht groß ist, dann ist es besser nicht mehr den split-Operator zu verwenden. Ansonsten ist der split-Operator dafür sehr gut geeignet.

($a,$b,$c)=split(/\s+/,$string)); # i. a. besser

($a,$b,$c)=$string=~/(\S+)\s+(\S+)\s+(\S+)/;

Will man ein ganz bestimmtes Element aus dem Ergebnis des Splittings haben, so kann man dies mit dem Zugriffsoperator [] erledigen (z. B.: (split(/\s+/,$string))[3]). Dieser ist jedoch langsamer als das Problem mit einem geeigneten regulären Ausdruck zu lösen:

$a=split(/\s+/,$string))[3];

($a)=$string=~/\S+\s+\S+\s+\S+\s+(\S+)/;
  # ($a) statt $a Perl gibt nur die Werte zurueck,
  # falls links ein Array steht. Ist dort eine
  # Skalarvariable, so wird 1 oder 0 zurueckgegeben.

SeitenanfangSeitenendeeq vs regulären Ausdrücken

Um Zeichenketten auf ihre Gleichheit zu überprüfen ist immer noch der eq-Operator der schnesllste:

if ($string eq 'yes') { ... } # am schnellsten

if ($string=~/^yes$/) { ... } # langsamer bzw. gleich schnell

Wird mit eq gearbeitet, so fährt man sicher, dass man so ziemlich das schnellste erwischt, falls man auf Gleichheit testen will. Wird keine Gleichheit erreicht, dann sind die regulären Ausdrücke gleich schnell. Bei Gleichheit verlieren die regulären Ausdrücke; sie sind dann nur noch halb so schnell.

Bemerkung: Wird ein Muster erkannt, so werden intern die Variablen $`, $& und $' gesetzt - das kostet Zeit.

SeitenanfangSeitenendeindex() und rindex() vs regulären Ausdrücken

Zum Finden von Teilstrings sind zwei weitere nützliche Operatoren index() und rindex() zu erwähnen. Diese testen einen String, ob im String ein angegebener Teilstring enthalten ist. Zurückgeliefert wird -1, falls der Teilstring nicht enthalten ist und der Index, an dem der Teilstring startet. index() bezieht sich dabei auf das erste Vorkommen des Teilstrings, rindex() auf das letzte Vorkommen. Die Syntax lautet: index($string, $teilString) bzw rindex($string, $teilString). Ein Beispiel:

$string="Hi Hans! Wie geht's Hans?";
#           ^                ^

$left = index($string,'Hans');
$right = rindex($string,'Hans');

print "Index des ersten Vorkommens:  ".$left."\n";
print "Index des letzten Vorkommens: ".$right."\n";

Liefert:

C:\>perl testIndex.pl
Index des ersten Vorkommens:  3
Index des letzten Vorkommens: 20

C:\>

Mit regulären Ausdrücken könnte man das wie folgt programmieren - was aber langsamer ist:

$string='Hi Hans! Wie geht's Hans?';

$string=~/Hans/;
$left=length($`);
$string=~/Hans.*?$/;
$right=length($`);

print "Index des ersten Vorkommens: ".$left."\n";
print "Index des letzten Vorkommens: ".$right;

SeitenanfangSeitenendesubstr() vs regulären Ausdrücken

Um Teilstrings in einem String zu extrahieren und zu verändern, eignet sich der Operator substr(). Ein Beispiel an dem es klar wird:

$string="Hi Hans! Wie geht's Hans?";

print substr($string,3,4)."\n\n";
  # liefert aus $string die naechsten 4 Zeichen ab Position 3
print substr($string,9)."\n";
  # liefert aus $string alle Zeichen ab Position 9

Das ergibt:

C:\>perl testSubstr.pl
Hans

Wie geht's Hans?

C:>

Das gleiche mit regulären Ausdrücken und langsamer:

$string="Hi Hans! Wie geht's Hans?";

$string=~/^.{3}(.{4})/;
print=$1."\n\n";
$string=~/^.{9}(.*)/;
print $1."\n";

SeitenanfangSeitenendetr/// vs s///

Man kann mit Hilfe von regulären Ausdrücken einzelne Zeichen ersetzen. Dazu bietet Perl eine speziellen Operator: tr///. Dieser eignet sich hervorragend, um einzelne Zeichen in andere umzuwandeln:

$string="Hans Otto Karl";
print $string."\n";

$string=~tr/ao/bt/;
print $string."\n";

Liefert:

C:\>perl testTr.pl
Hans Otto Karl
Hbns Ottt Kbrl

C:\>

Es werden die Zeichen eins zu eins ausgetauscht: a wird zu b und o zu t. Mit Hilfe dieses Operators kann man ziemlich schnell einiges anstellen - z. B. um etwas zu verschlüsseln:

$string="Hans Otto Karl";
print $string."\n";

$string=~tr/a-zA-Z/b-zaG-ZA-F/; # verschluesseln
print $string."\n";

$string=~tr/b-zaG-ZA-F/a-zA-Z/; # entschluessenln
print $string."\n";
C:\>perl testTr2.pl
Hans Otto Karl
Nbot Uuup Qbsm
Hans Otto Karl

C:\>

Wollte man so etwas mit s/// programmieren, so wäre dies sehr umständlich und sehr sehr langsam.

Bemerkung: Die obigen Operatoren sind speziell angepasste Routinen; d. h., sie wurden exakt für ihre Aufgabe zugeschnitten. Für alle (?) anderen Aufgaben, was Strings angeht, sind reguläre Ausdrücke immer noch das Beste was man kriegen kann.

Seitenanfang FehlermeldungHilfe zur Fehlermeldung © 2001-2003 Email an den AutorPerl, Lehrstuhl Mathe II, Uni Bayreuth