| HTML-Dateien selbst erstellen
|  | Dokumentation: CGI/Perl
|  |  | CGI und Perl: Perl Sprachelemente

# Zeichenketten und Listen manipulieren

Teile aus Zeichenketten extrahieren
Zeichenketten in Listen verwandeln
Listenelemente zu Zeichenkette verbinden
Listenelemente hinzufügen, ersetzen und löschen
Listenelemente sortieren
Suchen und Ersetzen von Zeichen oder Zeichenketten

## Teile aus Zeichenketten extrahieren

Sie können aus einer größeren Zeichenkette ein einzelnes Zeichen oder eine Zeichenfolge entnehmen.

#### Beispiel:

    #!/usr/bin/perl

    $Url = "http://www.teamone.de/selfhtml/teck.htm";

    $Stop = index($Url,":");
    $Protokoll = substr($Url,0,$Stop);
    $Start = index($Url,"//") + 2;
    $Domain = substr($Url,$Start);
    $Stop = index($Domain,"/");
    $Domain = substr($Domain,0,$Stop);
    $Start = rindex($Url,"/") + 1;
    $Dateiname = substr($Url,$Start);
    $Url_Laenge = length($Url);

    print "Das verwendete Internet-Protokoll der URL-Adresse lautet: ", $Protokoll, "\n";
    print "Die Domain-Adresse der URL-Adresse lautet: ", $Domain, "\n";
    print "Der Dateiname der URL-Adresse lautet: ", $Dateiname, "\n";
    print "Die URL-Adresse hat eine Laenge von: ", $Url_Laenge, " Zeichen\n";

#### Erläuterung:

Im obigen Beispiel wird aus einer URL-Adresse, die in dem Skalar $Url gespeichert wird, das Internet-Protokoll (im Beispiel: http), die Domain-Adresse (im Beispiel: www.teamone.de) und der Dateiname (im Beispiel teck.htm) extrahiert. Alle drei Teile der URL-Adresse werden in eigenen Skalaren gespeichert. Das Internet-Protokoll wird in $Protokoll gespeichert, die Domain-Adresse in $Domain und der Dateiname in $Dateiname. Am Ende des Scripts werden die ermittelten Teile mit der print-Funktion ausgegeben.

Die Perl-Funktion, mit deren Hilfe Sie eine Teilzeichenkette aus einer größeren Zeichenkette extrahieren können, heißt substr (= Unterzeichenkette). Diese Funktion erwartet zwei oder drei Parameter. Der erste Parameter ist die Zeichenkette, von der ein Teil extrahiert werden soll. Der zweite Parameter ist eine Zahl. Die Zahl gibt an, ab dem wievielten Zeichen der Zeichenkette die Teilzeichenkette extrahiert werden soll. Dabei wird bei 0 (für das erste Zeichen) zu zählen begonnen. Wenn Sie beispielsweise substr(Stefan,2) notieren, gibt die Funktion efan zurück. Als dritten Parameter können Sie substr noch mitteilen, wieviele Zeichen ab dem angegebgenen Startzeichen extrahiert werden sollen. Wenn Sie etwa substr(Stefan,2,3) notieren, erhalten Sie als Ergebnis efa.

Häufig wissen Sie jedoch nicht, an der wievielten Stelle einer Zeichenkette ein gewünschter, sinnvoller Teil beginnt. Dafür wissen Sie, daß die Zeichenkette einen bestimmten Aufbau hat. So ist es auch im obigen Beispiel. Die Zeichenkette stellt eine URL-Adresse dar. URL-Adressen haben bekanntlich einen einheitlichen Aufbau. Wenn Sie, wie im Beispiel, etwa die Domainadresse aus einer URL extrahieren wollen, wissen Sie, daß die Domainadresse hinter dem doppelten Schrägstrich // beginnt. Perl bietet dazu die Funktionen index und rindex an. Mit index ermitteln Sie, an der wievielten Stelle einer Zeichenkette ein bestimmtes Zeichen oder eine bestimmte Zeichenfolge zum nächsten mal vorkommt. Mit rindex ermitteln Sie, an der wievielten Stelle einer Zeichenkette ein bestimmtes Zeichen oder eine bestimmte Zeichenfolge zum letzten mal vorkommt. Beide Funktionen erwarten zwei Parameter. Als ersten Parameter übergeben Sie die Zeichenkette, in der nach dem Vorkommen eines Zeichens oder einer Zeichenfolge gesucht werden soll. Als zweiten Parameter bekommt die Funktion das Zeichen oder die Zeichenfolge übergeben, nach der gesucht werden soll. Beide Funktionen geben dann eine Zahl zurück. Diese Zahl können Sie dann in substr als zweiten Parameter übergeben. Wenn Sie beispielsweise index("Opa nahm Opium","Op") notieren, erhalten Sie 0 zurück, weil "Op" gleich am Anfang zum ersten mal vorkommt. Wenn Sie dagegen rindex("Opa nahm Opium","Op") notieren, erhalten Sie 9 zurück, da in diesem Fall das letzte Vorkommen von "Op" ermittelt wird.

Es ist sinnvoll, die Rückgabewerte der all dieser Perl-Funktionen in eigens dafür definierten Skalaren zu speichern, so wie im obigen Beispiel. Diese Skalare können Sie anschließend bequem weiterverarbeiten.

#### Beachten Sie:

Eine weitere interesante Funktion für Zeichenketten ist length (siehe Beispiel). Diese Funktion gibt die Anzahl Zeichen in einer Zeichenkette zurück.

## Zeichenketten in Listen verwandeln

Wenn Sie Zeichenketten haben, die bestimmte, regelmäßig vorkommende Zeichen enthalten, können Sie diese Zeichen als Trennzeichen behandeln und die Zeichenkette in eine Liste übertragen.

#### Beispiel:

    $CSV_Zeile = "Wilhemine Sauerapfel,Schlundstr. 13,90001 Neunhausen,099/12345";
    @Adresse = split(/,/,$CSV_Zeile,4);
    $i = 0;
    for(@Adresse)
     {
      print $i+1, ". Feld der Adresse: ", $Adresse[$i], "\n";
      $i++;
     }

#### Erläuterung:

Im obigen Beispiel ist in dem Skalar $CSV_Zeile eine typische Zeile aus einer kommabegrenzten Datei gespeichert. Viele Datenbank- und Tabellenkalkulationsprogramme bieten die Möglichkeit, strukturierte Daten in Form solcher kommabegrenzter Dateien abzuspeichern. Dateien dieser Art werden üblicherweise mit der Dateiendung .csv abgespeichert. Wenn Sie so eine Datei zeilenweise einlesen, erhalten Sie in jeder Zeile einen Inhalt von der Art, wie er im obigen Beispiel in $CSV_Zeile gespeichert ist.

Mit der Perl-Funktion split können Sie solche Inhalte in Felder aufteilen und in einer Liste speichern. Definieren Sie eine Liste wie im Beispiel die Liste @Adresse. Dieser Liste weisen Sie den Rückgabewert von split zu. Die Funktion split erwartet zwei, optional auch drei Parameter. Als ersten Parameter übergeben Sie einen regulären Ausdruck, mit dessen Hilfe der Feldtrenner ermittelt wird. Im obigen Beispiel ist das einfach das Kommazeichen. Als zweiten Parameter übergeben Sie die Zeichenkette, aus der die Liste erzeugt werden soll. Im Beispiel ist das der Skalar $CSV_Zeile. Als dritten Parameter können Sie der split-Funktion noch angeben, wie viele Felder sie maximal erzeugen soll. Im obigen Beispiel ist das eigentlich nicht nötig, aber der Vollständigkeit halber wird 4 übergeben, denn so viele Datenfelder enthält die Adressenzeile.

## Listenelemente zu Zeichenkette verbinden

#### Beispiel:

    #!/usr/bin/perl

    @Adresse = ("Wilhemine Sauerapfel","Schlundstr. 13","90001 Neunhausen","099/12345");
    $CSV_Zeile = join(",",@Adresse);
    print "Die erzeugte Zeichenkette lautet: ", $CSV_Zeile, "\n";

#### Erläuterung:

Im obigen Beispiel haben Sie eine Adresse in einer Liste @Adresse mit Feldern für die einzelnen Daten gespeichert. Diese Liste können Sie mit Hilfe der Mit der Perl-Funktion join in eine Zeichenkette verwandeln. Dabei geben Sie außerdem an, durch welches Zeichen oder welche Zeichenfolge die Felder in der zu erzeugenden Zeichenkette voneinander getrennt werden sollen. Die Funktion join ist also die Umkehrfunktion zu split.

Definieren Sie einen Skalar wie im Beispiel den Skalar $CSV_Zeile. Diesem Skalar weisen Sie den Rückgabewert von join zu. Die Funktion join erwartet zwei Parameter. Als ersten Parameter übergeben Sie das Zeichen oder die Zeichenfolge, durch die die Felder in der zu erzeugenden Zeichenkette voneinander getrennt sein sollen. Im Beispiel ist das einfach ein Kommazeichen. Als zweiten Parameter übergeben Sie die Liste, aus der die Zeichenkette erzeugt werden soll. Im Beispiel ist das die Liste @Adresse.

## Listenelemente hinzufügen, ersetzen löschen

Eine Liste muß keinen festen Inhalt und keine feste Länge haben. Sie können beispielsweise während des Programmlaufs zu einer Liste Elemente an eine Liste anhängen oder Elemente aus der Liste löschen.

#### Beispiel 1: Element hinzufügen

    #!/usr/bin/perl

    @Adresse = ("Wilhemine Sauerapfel","Schlundstr. 13","90001 Neunhausen","099/12345");
    push(@Adresse,"sauerapfel\@finster.de");
    for(@Adresse)
     {
      print $_, "\n";
     }

#### Beispiel 2: Element entfernen

    #!/usr/bin/perl

    @Adresse = ("Wilhemine Sauerapfel","Schlundstr. 13","90001 Neunhausen","099/12345");
    pop(@Adresse);
    for(@Adresse)
     {
      print $_, "\n";
     }

#### Beispiel 3: Element ersetzen

    #!/usr/bin/perl

    @Adresse = ("Wilhemine Sauerapfel","Schlundstr. 13","90001 Neunhausen","099/12345");
    $Adresse[1] = "Hasenschartenstr. 7";
    for(@Adresse)
     {
      print $_, "\n";
     }

#### Beispiel 4: Elemente umsortieren

    #!/usr/bin/perl

    @Adresse = ("Wilhemine Sauerapfel","Schlundstr. 13","90001 Neunhausen","099/12345");
    for($i=1;$i<3;$i++)
     {
      $Temp = shift(@Adresse);
      push(@Adresse,$Temp);
     }
    for(@Adresse)
     {
      print $_, "\n";
     }

#### Erläuterung:

Mit Hilfe der Perl-Funktion push können Sie ein Element an eine Liste anhängen. Im obigen Beispiel 1 wird an die Liste @Adresse ein Element angehängt, das eine E-Mail-Adresse enthält. Die Funktion push bekommt beim aufruf im ersten Parameter die Liste übergeben, an die Sie ein oder mehrere Elemente anhängen möchten. Dahinter geben Sie ein oder mehrere Elemente an, die Sie anhängen möchten. Das können Zeichenketten oder Zahlen sein. Im obigen Beispiel wird nur ein Element angehängt, nämlich die E-Mail-Adresse. Wenn Sie mehrere Elemente anhängen wollen, trennen Sie diese durch Kommata.
Der Schrägstrich in der E-Mail-Adresse gehört übrigens nicht zu der Adresse, sondern ist ein Maskierungszeichen für das Klammeraffenzeichen @, da dieses Zeichen in Perl eine eigene Bedeutung hat (es markiert Listen).

Mit Hilfe der Funktion pop können Sie das letzte Element einer Liste entfernen. Dazu übergeben Sie beim Aufruf der Funktion einfach die Liste, deren letztes Element Sie entfernen wollen. Im obigen Beispiel 2 ist das die Liste @Adresse. In dem Beispiel wird die Telefonnummer aus der Liste entfernt.

Um in einer Liste ein bestimmtes Element zu ersetzen, sprechen Sie einfach das betreffende Listenelement an und weisen ihm einen anderen Wert zu, so wie im obigen Beispiel 3.

Das obige Beispiel 4 zeigt, wie Sie die Elemente einer Liste "händisch" umsortieren können. Dazu eignet sich die Perl-Funktion shift. Diese Funktion entfernt das erste Element aus einer Liste und gibt es zurück. Alle weiteren Elemente rücken eins nach vorne, so daß das bislang zweite Element nun das erste wird usw. Damit das entfernte erste Element nicht verloren geht, können Sie es in einem Skalar zwischenspeichern. Im obigen Beispiel 4 wird das entfernte Element im Skalar $Temp zwischengespeichert. Mit der Funktion push wird dieses Element anschließend wieder ans Ende der Liste angehängt. Im Beispiel findet dieser Austausch innerhalb einer for-Schleife statt. Auf diese Weise lassen sich mehrere Elemente nacheinander umsortieren. In dem Beispiel stehen am Ende Ort und Telefonnummer der Adresse am Anfang der Liste, gefolgt von Name und Straße.

## Listenelemente sortieren

Eine sehr leistungsstarke Funktion in Perl ist die Möglichkeit, Listen zu sortieren.

#### Beispiel 1: Zeichenketten sortieren

    #!/usr/bin/perl

    @Freundinnen = ("Nina","Martina","Annina","Christina","Ina","Sabrina");
    @Ordnung = sort(@Freundinnen);
    for(@Ordnung)
     {
      print $_, "\n";
     }

#### Beispiel 2: Zahlen sortieren

    #!/usr/bin/perl

    @HighscoreListe = (9834,9837,5989,4509,4329,6509,2837,8289,10845);
    @SortierteListe = sort NummernSort @HighscoreListe;
    @AbsteigendSortierteListe = reverse @SortierteListe;
    for(@AbsteigendSortierteListe)
     {
      print $_, "\n";
     }

    sub NummernSort
    {
     if($a < $b)
      { return -1; }
     elsif($a == $b)
      { return 0; }
     else
      { return 1; }
    }

#### Erläuterung:

Zum automatischen Sortierung von Listen steht die Perl-Funktion sort zur Verfügung. Diese Funktion sortiert die Elemente einer Liste, die der Funktion als Parameter übergeben wird, automatisch alphabetisch in aufsteigender Reihenfolge. Wenn Sie genau das erreichen wollen, brauchen Sie nur einen Befehl wie im obigen Beispiel 1 der Befehl @Ordnung = sort(@Freundinnen). In diesem Beispiel wird die Liste @Freundinnen sortiert. Die sortierte Liste wird in @Ordnung gespeichert.

Schwieriger wird es, wenn Sie numerische Werte sortieren wollen, so wie im obigen Beispiel 2. Dazu brauchen Sie ein eigenes Unterprogramm, das ein bestimmtes Aussehen haben muß, da die sort-Funktion dieses Unterprogramm auf Wunsch aufruft. Das Unterprogramm NummernSort aus Beispiel 2 können Sie für all solche Zwecke verwenden. Mit der Anweisung @SortierteListe = sort NummernSort @HighscoreListe; wird im Beispiel die Liste @HighscroreListe numerisch sortiert. Lassen Sie bei diesem Funktionsaufruf am besten die Klammern weg und notieren Sie hinter sort den Namen des Unterprogramms für den Sortiervorgang, im Beispiel also NummernSort. Dahinter folgt die Angabe der Liste, die auf diese Weise sortiert werden soll, im Beispiel @HighscoreListe.

Wenn Sie eine Liste nicht aufsteigend, sondern absteigend sortiert haben wollen, können Sie die Perl-Funktion reverse anwenden. Im obigen Beispiel 2 wird die Liste @SortierteListe, die zunächst aufsteigend sortiert ist, mit der Anweisung @AbsteigendSortierteListe = reverse @SortierteListe; in eine neue Liste mit dem Namen @AbsteigendSortierteListe gespeichert. Diese Liste ist absteigend sortiert.

## Suchen und Ersetzen von Zeichenketten

Das mächtige Werkzeug der regulären Ausdrücke wird in Perl auch oft dazu benutzt, um in Zeichenketten bestimmte Zeichen oder Zeichenfolgen durch andere zu ersetzen, oder um bestimmte Zeichen oder Zeichenfolgen aus Zeichenketten zu entfernen. Dazu gibt es eine spezielle Syntax.

#### Beispiel 1: Alle Buchstaben und Leerzeichen entfernen

    #!/usr/bin/perl

    $Text = "Franz jagt im komplett verwahrlosten Taxi quer durch Bayern 1234567890";
    $Text =~ s/[a-z]| //gi;
    print $Text;

#### Beispiel 2: Deutsche Umlaute HTML-gerecht ersetzen

    #!/usr/bin/perl

    $Text = "In München steht ein Hofbräuhaus, dort gibt es Bier in Maßen";
    $Text =~ s/ä/\&auml\;/g;
    $Text =~ s/ö/\&ouml\;/g;
    $Text =~ s/ü/\&uuml\;/g;
    $Text =~ s/Ä/\&Auml\;/g;
    $Text =~ s/Ö/\&Ouml\;/g;
    $Text =~ s/Ü/\&Uuml\;/g;
    $Text =~ s/ß/\&szlig\;/g;
    print $Text;

#### Beispiel 3: Fehlerhafte Angaben entfernen und unterdrücken

    #!/usr/bin/perl

    @Schulnoten = (1,4,7,2,X,3,0,1,6,3,3,8,R,G,9,2,3,4,1,1,3);
    $Notenkette = join(",",@Schulnoten);
    $Notenkette =~ s/[7-9]|0|[A-Z]//gi;
    @NeueNoten = split(/,|,,/,$Notenkette);
    for(@NeueNoten)
     {
      unless($_ eq "")
       {
        print $_, "\n";
       }
     }

#### Erläuterung:

Das Schema für alle Suche-Ersetze-Vorgänge in Perl lautet:
Zeichenkette =~ s/Suchmuster/Ersetzmuster/[Optionen]

Zeichenkette ist meistens ein Skalar, in dem eine Zeichenkette gespeichert ist, so wie etwa $Text im obigen Beispiel 1. Dahinter notieren Sie die Zuweisung =~, gefolgt von einem Leerzeichen und dem kleinen Buchstaben s. Unmittelbar hinter dem kleinen s folgt ein reulärer Ausdruck, markiert durch die Schrägstriche /.../. In diesem Suchausdruck definieren Sie nach den Regeln für reguläre Ausdrücke, wonach in der Zeichenkette gesucht werden soll. Hinter dem abschließenden Schrägstrich folgt ein zweiter Ausdruck. In diesem Ausdruck notieren Sie das Zeichen oder die Zeichenfolge, durch die Fundstellen ersetzt werden sollen. Dahinter folgt nochmals ein abschließender Schrägstrich. Hinter diesem Schrägstrich können Sie mit Hilfe von erlaubten Kleinbuchstaben Optionen für den Suche-Ersetze-Vorgang definieren. Dabei sind folgende Buchstaben wichtig:
g sucht/ersetzt alle Fundstellen (ansonsten wird nur die erste Fundstelle ersetzt)
i sucht/ersetzt Buchstaben unabhängig davon, ob sie groß oder klein geschrieben sind (ansonsten wird Groß-/Kleinschreibung unterschieden)

Im obigen Beispiel 1 werden aus $Text alle Buchstaben (groß und klein) und alle Leerzeichen entfernt. Es bleiben anschließend also nur noch die Ziffern am Ende stehen.

Im obigen Beispiel 2 werden in $Text alle deutschen Umlaute und scharfes S durch ihre HTML-gerechten Umschreibungen ersetzt.

Im obigen Beispiel 3 werden aus der Liste @Schulnoten alle Werte entfernt, die nicht zwischen 1 und 6 liegen. Dazu wird die Liste zu einer Zeichenkette verbunden. Aus dieser Zeichenkette $Notenkette werden alle Ziffern entfernt, die nicht zwischen 1 und 6 liegen, sowie alle Buchstaben. Das Ersetzmuster bleibt dabei leer, was dazu führt, das die Fundstellen einfach entfernt werden. Anschließend wird die behandelte Zeichenkette in eine Liste verwandelt. Dabei werden mit dem regulären Ausdruck /,|,,/ auch alle leeren Elemente, die der Suche-Ersetze-Vorgang zurückgelassen hat, übergangen. Die neue Liste enthält nur noch gültige Schulnoten zwischen 1 und 6.

| Blättern: |
Dateien lesen und schreiben |  |  | Mit Zahlen und Zeit arbeiten

| HTML-Dateien selbst erstellen
|  | Dokumentation: CGI/Perl
|  |  | CGI und Perl: Perl Sprachelemente