CGI Programmierung
|
|
| | | | | Blog | Sitemap | Suchen | Webmaster | |
CGI-Programme können in jeder beliebigen Programmiersprache geschrieben werden, solange sie in der Lage ist, einen QUERY_STRING zu decodieren. Programmiersprachen, die eine ausgereifte Stringbehandlung und eine automatische Speicherverwaltung haben, sind besonders geeignet, denn CGI-Programme benutzen diese Spracheigenschaften meistens sehr intensiv. Ein Datenbankinterface oder andere Möglichkeiten, große Datenmengen zu durchsuchen, sind ein zusätzliches Plus, denn oft müssen CGI-Programme vorhandene Daten für die Darstellung im Web aufbereiten.
Die Programmiersprache Perl ist besonders geeignet zur Programmierung von CGI-Scripten, denn sie macht gerade die Bearbeitung von Texten und Dateien besonders einfach. Ursprünglich war Perl eine Sprache zur Reportgenerierung aus beliebig formatierten Systemlogbüchern. Daher stammen Perls umfangreiche Einbaufunktionen zum Suchen und Ersetzen von Texten und zur Formatierung von Reports. Die Weiterentwicklung hat Perl zu einem sehr mächtigen Werkzeug zur Systemprogrammierung und -steuerung in UNIX gemacht: Gerade die Systemverwalter größerer Installationen wissen Perl zu nutzen, um Wartungsabläufe auf ihren Systemen zu automatisieren. Auch die weite Verfügbarkeit von Perl auf praktisch allen Plattformen, die ausreichend Speicher zur Verfügung stellen, macht die Sprache für diese Zwecke interessant.
Mit dem Aufkommen des World Wide Web hat Perl eine Leistungsfähigkeit als Sprache zur schnellen Entwicklung von CGI-Programmen demonstriert. Ein sehr großer Teil aller CGI-Programme ist zunächst als Perl-Script entwickelt worden. Oft ist die Leistung diesr Scripte schon ausreichend, so daß eine Portierung in eine compilierte Sprache sich erübrigt.
Das berüchtigte ,,Hello, World!``-Programm sieht in Perl so aus:
#! /usr/bin/perl -- print "Hello, World\n";
Es sieht aus wie eine Kreuzung zwischen einem Shellscript und einem C-Programm. In der Tat ist Perl eine interpretierte Sprache, denn Perlprogramme müssen nicht compiliert werden, sondern können wie Shellscripte direkt aufgerufen werden. Genau wie bei UNIX-Shellscripten gibt die erste Zeile des Programms an, daß es sich um ein Script handelt und unter welchem Pfad der Interpreter für diese Scripte zu finden ist. Für das Script selbst ist eine Zeile, die mit einem # beginnt, ein Kommentar, so daß das Script selbst seinen eigenen Aufruf als Kommentar interpretiert.
Perlprogramme sind jedoch schneller als Shell-Scripte, denn der Interpreter übersetzt das Programm beim Aufruf in eine interne Form und bestimmt auch schon die Adressen der verschiedenen Funktionen und Variablen. In der Tat steht ein Perlprogramm einem C-Programm in der Geschwindigkeit nicht viel nach. Seine Ausführungsgeschwindigkeit ist der von P-Code vergleichbar, wie ihn einige Microsoft-Compiler zu Speicherersparniszwecken erzeugen.
Die Anweisung print druckt ihr Argument, einen String nach den Konventionen von C. Wie in C werden Anweisungen in Perl mit einem Semikolon beendet.
Die nächste Stufe der Komplexität nach ,,Hello, World!`` besteht in der Regel darin, den Namen der zu grüßenden Person einzulesen und diese Person namentlich zu begrüßen. Das erfordert die Verwendung von Operationen zur Eingabe von Daten und natürlich Variablen.
In Perl gibt es nur einen Typ von Variablen. Sie können entweder Strings, Integer oder Fließkommazahlen speichern und sie müssen nicht vereinbart werden. Perl-Variablen können jedoch in Form von einfachen Werten (Skalaren), numerisch indizierten Feldern (Arrays) oder beliebig indizierten Tabellen (assoziativen Feldern, Hashtables) auftreten. Skalare werden durch das Zeichen Dollar ($) gekennzeichnet, so daß $name eine skalare Variable mit dem Namen name bezeichnet. Diese Variable wird ins Leben gerufen, indem ihr einfach ein Wert zugewiesen wird.
Um nach einem Namen zu fragen, muß ein Prompt ausgegeben werden und auf irgendeine Weise eine Eingabe eingelesen werden. Den Prompt können wir bereits drucken, mit print. Eine Eingabe einzulesen, ist ebenfalls sehr einfach, denn wie in C stehen uns die vordefinierten Filehandles <STDIN>, <STDOUT> und <STDERR> zur Verfügung. Perl ist auf Stringverarbeitung optimiert: Um eine Zeile der Eingabe einzulesen, genügt es, einer Variablen das Filehandle zuzuweisen:
print "Wie ist Ihr Name? "; $name = <STDIN>;
Das Ergebnis ist, daß der Skalar $name eine Eingabezeile inklusive des Zeilenendezeichens enthält. Wir können dieses letzte Zeichen abschneiden, indem wir die Funktion chop() verwenden, die das letzte Zeichen eines Strings zurückliefert und als Seiteneffekt den String um dieses Zeichen kürzt.
chop($name);
Wie in Shell auch können Variablen in Stringkonstanten verwendet werden: Sie werden vor der Ausgabe durch ihren Wert ersetzt:
print "Hello, $name!\n";
Und wie in Shell auch muß das Dollarzeichen in einem String durch einen Backslash geschützt werden, wenn es ausgegeben werden soll.
Hier noch einmal das ganze Programm:
#! /usr/bin/perl -- print "Wie ist Ihr Name? "; $name = <STDIN>; chop($name); print "Hello, $name!\n";
Wie bereits erklärt, unterscheidet Perl nicht nach verschiedenen Datentypen, und Variablen müssen nicht vereinbart werden. Einer skalaren Variable kann so ziemlich jeder Wert zugewiesen werden, der sich in Perl darstellen läßt. Das können Zahlen wie 42 oder 3.1415926e00 sein oder Zeichenketten beliebiger Länge. Anders als Shell hat Perl keine Probleme mit binären Zeichen in Strings, ja nicht einmal Nullbytes machen Schwierigkeiten. Es ist kein Problem, in Perl Binärprogramme in Strings einzulesen, zu patchen und wieder zurückzuschreiben.
Perl wandelt skalare Werte intern automatisch in Zeichenketten oder in Fließkommazahlen um, je nachdem, welche Art von Operation mit dem Wert durchgeführt wird. Die Sprache kennt keine Ganzzahloperationen und arbeitet auch intern niemals mit ganzen Zahlen, sondern immer mit doppelt genauen Fließkommazahlen. Zahlen können in Perl wie in C notiert werden, Abbildung 4.1 gibt einen Überblick.

Abbildung 4.1: Zahlenformate in Perl.
Wie in der UNIX-Shell kann und muß man auch in Perl gelegentlich Zeichenketten in Anführungszeichen einschließen, etwa wenn sie Leerzeichen oder Sonderzeichen enthalten. In jedem Fall kann man einzelnen Sonderzeichen ihre Sonderbedeutung nehmen, indem man ihnen einen Backslash voranstellt. Das gilt natürlich auch für den Backslash (und die verschiedenen Sorten Anführungszeichen) selbst.
Einfache Anführungszeichen wirken so, als sei jedes einzelne Zeichen in der Zeichenkette von einem Backslash geschützt. Innerhalb der Zeichenkette darf jedes beliebige Zeichen auftauchen, auch Zeilenumbrüche, wenn sich die Zeichenkette über mehrere Zeilen erstreckt. Beispiele:
'Hello, World!' 'Don\'t do that, Dave!' '' # Der Leerstring. 'Dies ist der Backslash: \\.' 'multiline string'
Doppelte Anführungszeichen funktionieren eher so wie Strings in Shell und C: Innerhalb solcher Zeichenketten werden Variablen ersetzt, und einige Sonderzeichen können durch Backslash-Sequenzen notiert werden (Abbildung 4.2).
"Hello, World!" "Aufwachen!\007" "Spalte1\tSpalte2"

Abbildung 4.2: Controlzeichen in Perl.
Perl kennt dieselben numerischen Operationen auf Skalaren, die C auch kennt: +, -, *, / und %. Außerdem ist noch ein Potenzoperation ** definiert. Numerische Vergleiche werden mit den Operatoren <, <=, ==, >=, > und != vorgenommen.
Außerdem ist auf Strings die Konkatenation definier; dazu wird der Operator Punkt (.) verwendet. Strings können mit dem Operator x auch vervielfacht werden. Strings werden alphabetisch verglichen, dafür stehen die Operatoren lt, le, eq, ge, gt und ne zur Verfügung. Die numerischen Operatoren würden 7 < 30 als wahr bewerten, aber 7 lt 30 ist falsch.
Skalare können einfach zugewiesen werden, Perl verhält sich dabei im wesentlichen wie C. Der einzige Unterschied ist, daß Variablen nicht deklariert werden müssen, sondern nach Bedarf ins Leben gerufen werden. Wie in C existiert zu jedem arithmetischen Operator auch ein zugehöriger rechnender Zuweisungsoperator, d.h. man kann +=, -=, *=, /= und so weiter verwenden. Ebenso wie in C sind ++ und - als Pre- und Postoperatoren erlaubt.
Wird ein Skalar benutzt, bevor er einen Wert zugewiesen bekommen hat, liefert Perl den speziellen Wert undef. Dieser Wert sieht aus wie der Leerstring oder wie eine numerische Null, je nachdem, in welchem Kontext er verwendet wird. undef kann jedoch mit dem Prädikat defined() abgefragt werden. Das ist nützlich im Zusammenhang mit Dateien, die am Dateiende undef zurückliefern.
Außer skalaren Werten kann Perl noch Felder und assoziative Felder bearbeiten. Genau wie bei Strings gibt es auch bei diesen Datentypen keine Größenbegrenzungen, und genau wie gewöhnliche Variablen müssen auch die beiden Arten von Feldern in Perl nicht deklariert werden, sondern können einfach benutzt werden.
So wie skalare Variable durch ein $ bezeichnet werden, kennzeichnet Perl Felder mit einem @ und Hashlisten mit einem %-Zeichen. Demnach bezeichnet $name einen Skalar mit dem Namen name und @name ein Feld desselben Namens. Perl unterhält unterschiedliche Namensräume für alle drei Sorten von Objekten, so daß $name, @name und %name unterschiedliche Objekte bezeichnen.
Ebenso wie skalare Konstanten in Perl notiert werden können, existieren auch Notationen für Felder:
(1,2,3) # Ein Feld mit dem drei Werten 1, 2 und 3.
("huhu", "du", "da") # Ein Feld mit drei Strings.
Es ist auch möglich, gemischte Felder zu notieren, und die Feldelemente brauchen keine Konstanten zu sein:
($name, 42) # Der Wert von $name und 42. ($vorname + $nachname, $strasse + $hausnr) # Zwei Werte. () # Das leere (nullelementige) Feld.
Um große Listen von aufzählenden Zahlenwerten zu notieren, existiert in Perl außerdem noch eine Abkürzung:
(1..10) # Die ganzen Zahlen von 1 bis 10. (11.9..15.9) # Die Zahlen 11.9, 12.9, .., 15.9. (2, 3, 5..9) # Die Zahlen 2, 3, 5, 6, 7, 8 und 9. ($start..$stop) # Der Bereich von $start bis $stop.
Solche Listen zählen immer nur aufsteigend. Wenn der rechte Wert kleiner ist als der linke Wert, entsteht die leere Liste. Der Operator print kann ebenfalls Listen drucken; die Ausgabe erfolgt ohne Leerzeichen zwischen den Listenelementen:
print ("Der Name ist ", $name,"\n";
Arrays werden in Perl genauso zugewiesen wie Skalare, nämlich mit =. Perl erkennt, ob es sich um eine Zuweisung von Arrays oder Skalaren handelt, indem es die linke Seite der Zuweisung analysiert und feststellt, ob es sich dabei um einen skalaren oder um einen Arraykontext handelt.
@lall = (1..3); # Das Feld @lall besteht jetzt aus 3 Elementen. @bla = @lall; # In Perl können ganze Felder zugewiesen werden. @fasel = 1; # 1 wird zu (1) und dann zugewiesen.
In der Elementliste auf der rechten Seite der Zuweisung können auch wieder Arrays als Elemente auftauchen. Sie werden bei der Zuweisung durch ihre Elemente ersetzt. Auf diese Weise ist es möglich, vorne und hinten in das Feld Elemente einzufügen.
@lall = (1..3); @bla = (0, @lall, 4); # wird zu (0..4).
Enthält eine Liste nur Variablen, kann sie auch als linke Seite einer Zuweisung verwendet werden. Auf diese Weise kann man bequem beliebig viele Elemente eines Feldes permutieren. Wenn die linke Liste einer Zuweisung weniger Elemente hat als das Feld auf der rechten Seite, werden die überzähligen Elemente verworfen. Es ist aber auch möglich, als letztes Element der linken Seite ein Feld zu verwenden, das diese Elemente dann aufnimmt:
($b, $a) = ($a, $b); # $a und $b vertauschen. ($a, $b) = ($c, $d, $e); # $b ist $d, $e ist verloren. ($a, @b) = ($c, $d, $e); # $b[0] ist $d, $b[1] ist $e.
Wird ein Feld in einem skalaren Kontext verwendet, wird die Länge des Feldes für das Feld eingesetzt. Die Länge eines Feldes @name kann aber auch mit der Variablen $#name abgefragt werden.
Auf die Elemente eines Feldes @name kann durch Indizierung wie in C zugegriffen werden. Die Elemente eines Feldes sind Skalare, daher sind sie mit dem Prefix $ zu versehen. Es ist möglich, beliebigen einzelnen Feldelementen Werte zuzuweisen. Perl vergrößert das Feld nach Bedarf, eventuell vorhandene Lücken werden mit undef aufgefüllt.
print $name[0]; # das erste Element des Feldes @name. $name[0] = 17;
Anders als in C kann in Perl auch auf eine Liste von Arrayelementen zugegriffen werden. Dies wird als eine array slice bezeichnet. In diesem Fall handelt es sich um einen Arraykontext, daher also das Prefix @.
@fasel[0, 1]; # entspricht ($fasel[0], $fasel[1]) @fasel[1, 0] = @fasel[0, 1]; # Feldelemente tauschen. @fasel[0, 1, 2] = @fasel[1, 1, 1]; @fasel[9, 10] = (17, 4);
Mit den Operatoren push und pop kann Perl ein Array wie einen Stack verwenden. Es ist möglich, mehrere Werte (oder ganze Felder) auf einmal zu pushen.
push(@einStack, $einWert); push(@einStack, 4, 5, 6); $einWert = pop(@einStack);
Während push und pop die rechte Seite eines Arrays bearbeiten (d.h. an den hohen Indizes manipulieren), verändern shift und unshift die linke Seite des Feldes. shift entspricht dabei dem gleichnamigen Shell-Operator, und unshift ist seine Umkehrung.
reverse liefert die Elemente eines Feldes in
umgekehrter Reihenfolge, sort liefert sie alphabethisch
sortiert
, und
chop ist auch auf alle Elemente eines Feldes anwendbar.
Dateihandles wie <STDIN> können auch Arrays zugewiesen werden. Sie lesen dann die ganze Datei auf einmal ein und weisen jede Zeile einem Feldelement zu.
#! /usr/bin/perl -- @lines = <STDIN>; @reverselines = reverse(@lines); @sortlines = sort(@lines); print @sortlines; print @reverselines;
In Perl werden wie in C Blöcke von Anweisungen gebildet, indem man die Anweisungen in geschweifte Klammern einschließt. Diese Anweisungen werden linear ausgeführt.
{
anweisung_1;
anweisung_2;
...
anweisung_n;
}
Wie in C ist es möglich, Bedingungen zu formulieren. Anders als in C müssen die geschweiften Klammern immer vorhanden sein, auch dann, wenn nur eine Anweisung von der Bedingung abhängig ist. Der else-Block kann weggelassen werden. Mit Hilfe von elsif können Entscheidungen kaskadiert werden, ohne daß sich die Einrücktiefe bis ins Unendliche steigert.
if (bedingung) {
anweisungen;
} elsif (neue_bedingung) {
anweisungen;
else {
anweisungen;
}
In Perl werden Bedingungen als Strings berechnet. Bedingungen sind genau dann falsch, wenn sie entweder genau den String 0 oder den leeren String ergeben. Alle anderen Werte (1, 17, 0.000, 00) sind wahr.
Eine etwas seltsame Konstruktion in Perl ist die unless-Anweisung, die im Prinzip ein if ohne then darstellt (Die Anweisung die beendet ein Perl-Programm mit einer Fehlermeldung).
print "Wie ist Dein Name? ";
$name = <STDIN>;
unless ($name eq "Kristian") {
die "Zugriff verweigert.\n";
}
Eine andere seltsame Konstruktion ist das einzelnen Anweisungen nachgestellte if oder unless.
die "Zugriff verweigert.\n" unless ($name eq "Kristian);
Perl ist in der Lage, einen Block von Anweisungen zu wiederholen, solange eine Bedingung wahr (while) oder falsch (until) ist. Ebenso ist eine zu C analoge for-Anweisung zum Zählen vorhanden. Die Syntax ist in allen Fällen wie in C, nur daß die geschweiften Klammern nicht entfallen dürfen.
while (bedingung) {
anweisungen;
}
until (bedingung) {
anweisungen;
}
for (start_anweisungen; test_anweisungen; zählanweisungen) {
arbeits_anweisungen;
}
Zusätzlich ist Perl in der Lage, einen Block für jedes Element eines Feldes auszuführen. Das ist bequemer, als erst die Länge eines Feldes zu bestimmen und es dann durchzuzählen.
foreach $zähler (@eineListe) {
anweisungen;
}
Schleifen können mit last und next vorwärts und rückwärts kurzgeschlossen werden, d.h. last entspricht dem break in C und next entspricht dem continue von C.
Blöcke können in Perl mit einem Label markiert werden. last und next können mit Hilfe dieser Labels mehrere Ebenen auf einmal verlassen oder kurzschließen.
Assoziative Arrays oder Hashlisten sind programmtechnisch eine Verallgemeinerung von Arrays. Statt ganzzahliger Ausdrücke kann in einer Hashliste ein beliebiger String als Index verwendet werden. Über diesen String kann jederzeit auf dem mit dem String assoziierten Wert zugegriffen werden. Man kann sich eine solche Hashliste auch als Tabelle mit zwei Spalten vorstellen: Jedem String aus der linken Spalte (den Schlüsseln) ist der zugehörige String auf der rechten Seite (ein Wert) zugeordnet. Anders als in einer richtigen Tabelle oder in einem Array haben die Elemente in einer Hashliste aber keine vorgegebene Ordnung. Würde man sie aufzählen (z.B. in einer foreach-Schleife), bekäme man irgendeine Reihenfolge.
In Perl werden assoziative Felder durch ein Prozentzeichen (%) markiert. In einem Arraykontext werden sie wie ein normales Array mit einer geraden Anzahl von Feldern behandelt. Die geraden Positionen dieses Arrays beginnend bei 0 sind mit Schlüsseln belegt, die ungeraden Positionen mit den zu diesen Schlüsseln gehörenden Werten. Die Funktion keys() liefert die Schlüssel eines solchen Feldes und die Funktion values() die Werte.
%vorname_von = ( "Köhntopp", "Kristian",
"Seeger", "Martin",
"Rump", "Birgit");
# Reihenfolge ist zufällig!
print keys(%vorname_von); # Köhntopp, Seeger, Rump
print values(%vorname_von); # Kristian, Martin, Birgit
Der Zugriff auf einzelne Elemente erfolgt wie bei Feldern durch Indizierung, aber der Indexoperator besteht hier aus den geschweiften Klammern.
# Reihenfolge ist zufällig
foreach $i (keys(%vorname_von)) {
print "Der Vorname von $i ist $vorname_von{$i}.\n";
}
foreach $i (sort keys %vorname_von) {
print "Der Vorname von $i ist $vorname_von{$i}.\n";
}
Einzelne Elemente lassen sich mit dem Operator delete aus dem Feld löschen (man kann auch das ganze Feld löschen).
Wie bereits gezeigt, kann man eine Zeile der Eingabe einlesen, indem man das Filehandle der Eingabe an eine skalare Variable zuweist. Wenn keine Eingabezeile mehr verfügbar ist, wird der Wert undef zugewiesen. Weist man ein Filehandle statt dessen an ein Array zu, wird die gesamte Datei bis zum Dateiende zugewiesen und jedem Arrayelement eine Zeile zugeordnet.
Oft möchte man eine Datei zeilenweise durchlesen und für jede Zeile einer Operation ausführen. Für die Standardeingabe sieht das so aus:
while ($i = <STDIN>) {
print $i; # Zeile drucken
}
Die Schleife beendet sich am Dateiende, da der Wert undef zum Leerstring expandiert und dieser String als false-Wert gilt. Leere Eingabezeilen bestehen aber immerhin noch aus einem Newline-Zeichen, sind also keine Leerstrings.
In Perl ist es so, daß für viele Operatoren die Variable $_ als Defaultvariable angenommen wird, wenn keine Variable angegeben wird. Tatsächlich kann man das Beispiel auch so schreiben:
while (<STDIN>) {
print; # Zeile drucken
}
In diesem Fall wird statt der Variablen $i die Standardvariable $_ verwendet.
Die Kommandozeilenparameter eines Perlprogrammes stehen in der vordefinierten Arrayvariablen @ARGV zur Verfügung. Das spezielle Dateihandle <> interpretiert diese Namen der Reihe nach als Dateinamen und liest alle diese Dateien durch. Das Programm
#! /usr/bin/perl --
while (<>) {
print; # Zeile drucken
}
entspricht also dem UNIX-Kommando cat. Es kann perlcat a b c aufgerufen werden und gibt nacheinander die Inhalte aller drei Dateien als eine Datei auf der Standardausgabe aus.
Im assoziativen Array %ENV stellt Perl alle Umgebungsvariablen zur Verfühgung. Die Schlüssel sind jeweils der Name, die Werte sind die Werte der Umgebungsvariablen.
#! /usr/bin/perl --
# Finde den Pfad des Homeverzeichnisses
# des Benutzers.
print $ENV{'HOME'};
Wem die Ausgabe von Variablen mit print zu langweilig oder zu umständlich ist, der kann statt dessen printf verwendet. Diese Anweisung akzeptiert einen Formatstring wie die gleichnamige C-Funktion und eine Liste von Variablen, die entsprechend dem Formatstring formatiert werden.
printf "%10s %05d %7.2f\n", $s, $i, $f;
Viele Perl-Anweisungen und Funktionen machen von regulären Ausdrücken Gebrauch. Ein regulärer Ausdruck ist ein Suchmuster, das gegen eine Zeichenkette verglichen wird und entweder paßt oder nicht. Oft kommt es nur darauf an, ob der Ausdruck paßt oder nicht, manchmal möchte man auch noch wissen, welcher Teil der Zeichenkette genau gepaßt hat, etwa um ihn zu ersetzen.
Reguläre Ausdrücke werden von vielen UNIX-Programmen verwendet, darunter grep, sed, awk, ed, vi, emacs und die verschiedenen Shells. Jedes dieser Programme hat eine leicht unterschiedliche Art der Notation für reguläre Ausdrücke, und auch die Leistungsfähigkeit unterscheidet sich gelegentlich etwas. Perls reguläre Ausdrücke sind eine Obermenge aller dieser Verfahren: Jeder reguläre Ausdruck, der in einem der genannten Werkzeuge formuliert werden kann, kann auch in Perl formuliert werden, muß aber evtl. leicht umformuliert werden.
In Perl werden reguläre Ausdrücke notiert, indem sie in Schrägstriche (slashes) eingeschlossen werden. Die einfachste Form von regulären Ausdrücken sieht so aus:
if (/abc/) {
print "$_";
}
Im Beispiel wird die Einbauvariable $_ gegen den regulären Ausdruck getestet und wenn eine Übereinstimmung erzielt wird, wird der String gedruckt. Die volle Syntax des match-Operators lautet
$variable =~ m/regexp/optionen;
Dieser Ausdruck vergleicht den Inhalt der Variablen $variable gegen den regulären Ausdruck regexp. Dabei kann der Ablauf des Matchvorgangs mit einigen einbuchstabigen Operationen beeinflußt werden (die wichtigste Option ist i, ignore case). Auch die Trennzeichen (Slashes) können durch andere, frei gewählte Trennzeichen ersetzt werden. Der Match selbst ergibt einen Wahrheitswert, ,,1`` oder den Leerstring.
Perl kennt die folgenden Regeln zur Konstruktion von regulären Ausdrücken:
| Kürzel | Bedeutung | Kürzel | Bedeutung |
| [0-9] | [ |
||
| [a-zA-Z0-9_] | [ |
||
| [ |
[ |
Der Stern ist also ein Kürzel für
0,
, das Pluszeichen
steht für
1,
und das Fragezeichen für
0,1
.
Nach einem Match (und bis zum nächsten Gebrauch des Match-Operators) stehen die markierten Teilstrings in den besonderen Perl-Variablen $1, $2 und so weiter zur Verfügung.
Außerdem binden die Klammern Teilausdrücke zusammen: abc* paßt auf ab, abc, abcc und so weiter, während (abc)* auf den leeren String, abc, abcabc und so weiter paßt.
Außer dem m-Operator zum Matchen kennt Perl auch noch einen s-Operator zum Suchen und Ersetzen in einem String:
$variable =~ s/alt/neu/optionen;
Diese Operation ersetzt in der Variablen $variable alle
Vorkommen des regulären Ausdrucks alt durch
neu. Der Ausdruck neu darf dabei ebenfalls
Klammermarkierungen enthalten. So würde s/a(.+)b/x
1y/ in einem String ein Vorkommen von paarigen
a und b durch passende x und y
ersetzen, ohne daß der Text dazwischen irgendwie
beeinflußt wäre.
Außer der Option i (ignore case) kennt der s-Operator auch noch die Option g (global search and replace), die nicht nur ein einzelnes Vorkommen von alt ersetzt, sondern alle.
Die Perlfunktion split() kann dazu verwendet werden, einen Skalar mit Hilfe eines regulären Ausdrucks in ein Feld zu zerlegen. split() nimmt dazu den String und wendet den regulären Ausdruck wiederholt auf den String an. Alle Teile des Strings, die auf den regulären Ausdruck passen, werden zu Trennzeichen, und die Teile des Strings, die nicht auf den Ausdruck passen, werden zu Feldelementen.
Eine Zeile der Paßwortdatei in UNIX sieht zum Beispiel so aus:
$line = "kris:x:100:20:Kristian Köhntopp:/home/kris:/bin/bash";
Mit dem Aufruf split(/:/, $line); wendet Perl den regulären Ausdruck /:/ auf diese Zeile an. Der Ausdruck paßt auf alle Doppelpunkte, diese werden also Trennzeichen. Die Worte kris, x, 100, 20, Kristian Köhntopp, /home/kris und /bin/bash werden die Feldelemente 0 bis 6 des Ergebnisfeldes von split.
Wendet man split() in einem Arraykontext an, bekommt man das gesamte Feld als Ergebnis (und kann seine Länge mit $#feld feststellen). In einem skalaren Kontext bekommt man von split() die Länge des Feldes als Ergebnis.
$laenge = split(/:/, $line); # ergibt 6
@feld = split(/:/, $line); # ergibt $feld[0] = "kris" usw.
# $#feld ist auch 6.
Andererseits kann man mit join() ein Feld mit beliebigen Trennzeichen zu einem Skalar zusammenfügen.
$line = join(":", @feld);
würde das zerlegte Paßwortfeld von oben wieder zusammensetzen.
Es ist möglich, in Perl eigene Funktionen zu definieren. Die Syntax ist folgendermaßen:
sub name {
anweisungen;
$wert;
}
Diese Anweisungen definieren eine Funktion mit dem Namen name, die einen Rückgabewert in $wert berechnet. Die Namen von Funktionen sind von den Namen von Skalaren, Arrays und Hashlisten unabhängig. Funktionen werden mit einem Undzeichen aufgerufen. Die Funktion name kann also so aufgerufen werden:
&name; # name aufrufen und das Ergebnis verwerfen. $var = &name; # name aufrufen und das Ergebnis nutzen.
Funktionen können mit Argumenten aufgerufen werden. Diese Argumente stehen im Feld @_ zur Verfügung. Sie können also mit $_[0] und so weiter angesprochen werden.
sub add {
$summe = 0;
foreach $i (@_) {
$summe += $i;
}
$summe;
}
print &add(1, 42, 17, 4);
print &add(1..5);
Variablen in Funktionen sind global. Die Variable $summe in der Funktion oben würde also eine gleichnamige Variable anderswo im Programm überschreiben. Mit Hilfe des Operators local() ist es möglich, lokale Variablen zu deklarieren:
sub add {
local($summe) = 0;
foreach $i (@_) {
$summe += $i;
}
$summe;
}
Auf diese Weise kann man auch die Funktionsparameter in ein bekanntes Feld umkopieren:
sub add {
local(@werte) = @_;
local($summe) = 0;
foreach $i (@werte) {
$summe += $i;
}
$summe;
}
| Top | Geändert:15-Feb-2004 15:10:09 Url: http://kris.koehntopp.de/artikel/cgi/node4.html |