Peter: Externen String auslesen

Hi Leute!

Ich habe ein Problem und bekomme es einfach nicht in die Reihe:

In einer externen Datei (muster.csv) habe ich verschiedene Daten gespeichert, die durch Semikola getrennt sind.

Hier ein Beispiel:
Name1;10;11;12;http://www.name1.de/name1.htm;
Name11;14;;12;http://www.name11.de/noname.htm
Name100;300;1;12;http://www.name100.de/example.htm;http://www.name100.de/example2.htm
...

Jetzt möchte ich über ein HTML-Suchformular ein Perl-Skript starten, was nach verschiedenen Namen oder Werten sucht und ein Suchergebnis anzeigt. Leider habe ich es bis jetzt noch nicht geschafft, die Suche so zu modifizieren, daß in den Werten zwischen den Semikola gesucht wird. Anfänglich habe ich es mit substr versucht, aber das geht ja leider nur, wenn die Werte eine einheitliche Länge haben.

Kann mir jemand weiterhelfen?

  1. Hoi,

    In einer externen Datei (muster.csv) habe ich verschiedene Daten gespeichert,
    die durch Semikola getrennt sind.

    Um welche Datenmengen handelt es sich denn?

    Hier ein Beispiel:
    Name1;10;11;12;http://www.name1.de/name1.htm;
    Name11;14;;12;http://www.name11.de/noname.htm
    Name100;300;1;12;http://www.name100.de/example.htm;http://www.name100.de/example2.htm
    ...

    Jetzt möchte ich über ein HTML-Suchformular ein Perl-Skript starten, was nach
    verschiedenen Namen oder Werten sucht und ein Suchergebnis anzeigt. Leider
    habe ich es bis jetzt noch nicht geschafft, die Suche so zu modifizieren, daß
    in den Werten zwischen den Semikola gesucht wird. Anfänglich habe ich es mit
    substr versucht, aber das geht ja leider nur, wenn die Werte eine einheitliche
    Länge haben.

    Kann mir jemand weiterhelfen?

    Ich glaube, split() hilft dir weiter:

    my @entries = split /;/,$zeile;

    Naehere Infos findest du unter perldoc -f split oder auch auf
    http://www.perldoc.com. Aber bei groesseren Datenmengen ist das eine
    ungenuegende Suchmethode: sie ist zu langsam.

    Gruesse aus dem schoenen LH,
     c.j.k

    1. Hoi,

      ggf. ist das noch interessant:
      (?=pattern)
      A zero-width positive lookahead assertion. For example, /\w+(?=\t)/ matches a word followed by a tab, without including the tab in $&.

      (?lt=pattern)
      A zero-width positive lookbehind assertion. For example, /(?<=\t)\w+/ matches a word following a tab, without including the tab in $&. Works only for fixed-width lookbehind.

      siehe perldoc perlre

      K@rl

    2. Hi nochmal!

      Danke für Deine schnelle Antwort.

      Um welche Datenmengen handelt es sich denn?

      In der Datei sollen zukünftig ca. 100 Einträge zu finden sein.

      Ich habe das Skript jetzt so geschrieben, jedoch funzt es immernoch nicht. :-(

      open(DATEI,"<muster.csv") || die "Datei nicht gefunden";
      while(@zeile = <DATEI>)
      {
        $aid = substr($zeile,0,6);
        $mid = substr($zeile,8,6);
        print "A-ID: $aid, M-ID: $mid<br>";
        my @entries = split( /;/ ,$zeile);
        print "URL: $entries[5]";
      }
      close(DATEI);

      Was hab ich falsch gemacht?

      1. Hallo,

        Um welche Datenmengen handelt es sich denn?
        In der Datei sollen zukünftig ca. 100 Einträge zu finden sein.

        Na, das dürfte nicht zu wirklcihen Problemen führen.

        Ich habe das Skript jetzt so geschrieben, jedoch funzt es immernoch nicht. :-(

        open(DATEI,"<muster.csv") || die "Datei nicht gefunden";
        while(@zeile = <DATEI>)
        {
          $aid = substr($zeile,0,6);
          $mid = substr($zeile,8,6);
          print "A-ID: $aid, M-ID: $mid<br>";
          my @entries = split( /;/ ,$zeile);
          print "URL: $entries[5]";
        }
        close(DATEI);

        Was hab ich falsch gemacht?

        1.)@zeile = <DATEI>
         Das wird genau einmal aufgerufen, nämlich um ein Array mit dem gesamten Inhalt der Datei zu füllen. Somit wird der Block der While-Schleife maximal einmal durchlaufen.
        Gleichzeitig ergibt sich dadurch, daß $zeile nie mit einem Inhalt versehen wird, wordurch alles weitere im Block zu keinen brauchbaren Ergebnisssen führt.

        2.) Du hast den Sinn, bzw. deren Unterschiede, von substr und split noch nicht verstanden.

        substr kannst Du verwenden, wenn Du genau weißt wieviele Zeichen Du aus einer Zeichenkette ab einer bestimmte Stelle ermitteln willst.Das Ergebnis wird immer ein einzelener Wert, also ein Skalar, sein.

        split wirst Du verwenden, wenn Du die Zeichenfolge an bestimmten Zeichen, oder auch Zeichenfolgen, trennen willst. Das Ergebnis wird immer eine Liste von Werten sein.

        Dein Problem kannst Du ohne weiteres nur mit split lösen.

        3.) Du verwendest nicht 'use strict;'. Würdest Du es verwenden, so hättest Du schon eher gesehen, daß @zeile und $zeile zwei vollkommen verschiedene Variablen sind, und daß dann irgendetwas nicht stimmt.

        Hier nocheinmal ein Beispiel (allerdings nicht genau Deines und nicht zu sehr perlish):

        #!/usr/bin/perl -w
        use strict;

        open(IN,'was_auch_immer') or die 'Kann was_auch_immer nicht oeffnen: '.$!;
        my($eingangszeile);
        while($eingangszeile = <IN>)
           {
           chomp $eingangszeile; # damit die Zeilenumbrueche entfernt werden
           my(@werte) = split(/;/,$eingangszeile);
           # Ab hier wird was mit @werte gemacht
           }
        close(IN) or die 'verd..., zumachen von was_auch_immer geht nicht: '.$!;

        jetzt könntest Du noch einige Verfeinerungen anbringen. Wenn Du etwa vorher weißt, wie viele Spalten (hier acht) Deine Zeile haben wird

        my(@werte) = split(/;/,$eingangszeile,8);

        Oder Du könntest auch gleich Variablen befüllen, um es lesbarer zu machen

        my($name,$vorname,$strasse,$ort,$plz,$email,$url,$telefon) = split(/;/,$eingangszeile,8);

        uswusf...

        Grüße
          Klaus