Lev Benenson: Matching Operator (Perl sucht nicht die spitzen Klammern)

Hi alle zusammen

Ich habe mit Perl folgende Probleme:

Ich habe eine HTML-Datei (doz.html). Das ist eine lange Tabelle, die aus 4
Spalten besteht. Der Quelltext einer  Zeile der Tabelle ist folgender:
....
<tr>
<td>HERZ</td> <!-- kuenftiger KEY in assoziativen Arrey -->
<td>Dipl.-Ing. Ronald Herzer</td>
<td>FbB</td>
<td>tätig für FbB/AR</td>
</tr>
....u.s.w.

Ich versuche ein assoziatives Arrey zu erstellen. In diesem Arrey muß KEY aus erster Spalte der Tabelle erstellt werden und VALUE aus den nächsten drei Spalten, getrennt durch Komma. Natürlich muessen alle Täge in spitzen Klammern in den assoziativen Arrey nicht vorkommen. Für diesen  Zweck habe ich folgendes gemacht:

1. Zuerst habe ich mein HTML-Datei (doz.html) in eine Zeile umgewandelt,  weil Perl zeilenweise arbeitet, und in andere Datei (doz.txt) gespeichert,:

$pfad1 ="c:\test\doz.html";
       open(DATEI1, "$pfad1");
       @inhalt1 = <DATEI1>;
       $pfad2 ="c:\test\doz.txt";
       open (DATEI2, ">$pfad2");
       foreach $zeile1 (@inhalt1){
       chomp $zeile1;
       }
       print DATEI2 "@inhalt1\n";
       close DATEI2;

2. Danach:

$pfad2 ="c:\test\doz.txt";
       open (DATEI2, "$pfad2");
       @inhalt2 = <DATEI2>;

$pfad3 ="c:\test\dozarrey.txt";
       open (DATEI3, ">>$pfad3");
          foreach $zeile2 (@inhalt2) {       # doz.txt besteht nur aus eine Zeile
             if ($zeile2 =~ m/<tr><td>(.*?)</td><td>(.*?)</td><td>(.*?)</td><td>(.*?)</td></tr>/g) {
                 $key=$1;
                 $value="$2$a$3$a$4";    # $a= ", ";
                 print DATEI3 "$key$b$value$c\n";     # $b= "", ""; $c="",\n"";
             }
         }
.........

Meine Problem, dass Perl  nicht die spitzen Klammern suchen will, deshalb Datei dozarrey.txt immer leer bleibt.  Wo ist der Fehler?

Ich bedanke mich für jede Hilfe

  1. Hi auch,

    if ($zeile2 =~ m/<tr><td>(.*?)</td><td>(.*?)</td><td>(.*?)</td><td>(.*?)</td></tr>/g) {
    Meine Problem, dass Perl  nicht die spitzen Klammern suchen will,

    Bist Du Dir da sicher?
    (Beispielsweise, daß nicht irgendwo *ein* einziges
    Zeichen von Deiner Erwartungshaltung abweicht?)

    Wenn ich Fehler in einem so umfangreichen regular
    expression habe, dann kommentiere ich ihn erst mal
    aus und baue ihn mir schrittweise von links nach
    rechts wieder auf (im Schleifenkörper darf ich dann
    erst mal nur "print" machen und nix Destruktives).
    Solange er matcht, füge ich pro Versuch einen weiteren
    Term aus meiner Vorlage wieder ein.
    Auf diese Weise finde ich zuverlässig und relativ
    schnell die Stelle, wo es nicht mehr matcht - und
    damit auch meinen Denkfehler ...

    mfG - Michael

  2. Hi,

    $pfad1 ="c:\test\doz.html";
           open(DATEI1, "$pfad1");
           @inhalt1 = <DATEI1>;
           $pfad2 ="c:\test\doz.txt";
           open (DATEI2, ">$pfad2");
           foreach $zeile1 (@inhalt1){
           chomp $zeile1;
           }
           print DATEI2 "@inhalt1\n";
           close DATEI2;

    Du hast hier den inhalt von "doz.html" nach "doz.txt" kopiert und dann noch ein "\n" dazugegeben,
    sonst sind die Dateien identisch, weil in der foreach-Schleife ja am inhalt von @inhalt1 nichts verändert wurde.
    ich glaube Du wolltest folgendes machen
    open(DATEI1,"$pfad1");
    open(DATEI2,">$pfad2");
    print DATEI2 chomp while <DATEI1>;
    close(DATEI1);
    close(DATEI2);

    1. Danach:

    $pfad2 ="c:\test\doz.txt";
           open (DATEI2, "$pfad2");
           @inhalt2 = <DATEI2>;

    $pfad3 ="c:\test\dozarrey.txt";
           open (DATEI3, ">>$pfad3");
              foreach $zeile2 (@inhalt2) {       # doz.txt besteht nur aus eine Zeile
                 if ($zeile2 =~ m/<tr><td>(.*?)</td><td>(.*?)</td><td>(.*?)</td><td>(.*?)</td></tr>/g) {
                     $key=$1;
                     $value="$2$a$3$a$4";    # $a= ", ";
                     print DATEI3 "$key$b$value$c\n";     # $b= "", ""; $c="",\n"";
                 }
             }
    .........

    Hier liegt wirklich eine zu restriktive REGEX Deinem Problem zugrunde.
    Eine REGEX versucht in erster Linie, ein gültiges Matching zu erreichen. Bei Dir kann's Deinem Beispiel zufolge schon allein deshalb nicht funktionieren,
    weil zwischen erster und zweiter Spalte ein Kommentar eingfügt ist, welcher durch die Regex nicht aufgelöst werden kann
    wie siehts mit Attributen aus usw. ziemlich heavy, sag ich Dir.
    Vielleicht probierst Du einmal ein Perl-Modul aus, welches Dir vielleicht helfen kann. HTML-Tree z.B.
    XML-Module könnten vielleicht auch helfen, ist nur so eine Idee.

    1. Hi, Klaus,

      $pfad1 ="c:\test\doz.html";
             open(DATEI1, "$pfad1");
             @inhalt1 = <DATEI1>;
             $pfad2 ="c:\test\doz.txt";
             open (DATEI2, ">$pfad2");
             foreach $zeile1 (@inhalt1){
             chomp $zeile1;
             }
             print DATEI2 "@inhalt1\n";
             close DATEI2;
      Du hast hier den inhalt von "doz.html" nach "doz.txt" kopiert und dann noch ein "\n" dazugegeben,
      sonst sind die Dateien identisch, weil in der foreach-Schleife ja am inhalt von @inhalt1 nichts verändert wurde.

      Ja, das war mein Ziel. Die Dateien "doz.html" und "doz.txt" sind inhaltlich identisch, aber doz.txt besteht
      aus nur eine Zeile und ich dachte, dass in eine Zeile leichter in meinem Fall zu matchen, weil, wie
      Du erinnern kanst, muss ich sonst fuer das assoziatives Arrey VALUE von drei Zeilen in doz.html
      "zusammenkleben", und das ist viel komplizierter (nach meine Meinung).
      Zur Erinnerung.  doz.html sieht so aus:
      ....
      <tr>
      <td>HERZ</td>                                  <!-- kuenftiger KEY in assoziativen Arrey -->
      <td>Dipl.-Ing. Ronald Herzer</td>        <!-- kuenftiger 1.Teil von VALUE in assoziativen Arrey-->
      <td>FbB</td>                                    <!-- kuenftiger 2.Teil von VALUE in assoziativen Arrey-->
      <td>tätig für FbB/AR</td>  <!-- kuenftiger 3.Teil von VALUE in assoziativen Arrey-->
      </tr>
      ....u.s.w.

      Hier liegt wirklich eine zu restriktive REGEX Deinem Problem zugrunde.
      Eine REGEX versucht in erster Linie, ein gültiges Matching zu erreichen. Bei Dir kann's Deinem Beispiel zufolge schon allein deshalb nicht funktionieren,
      weil zwischen erster und zweiter Spalte ein Kommentar eingfügt ist, welcher durch die Regex nicht aufgelöst werden kann
      wie siehts mit Attributen aus usw. ziemlich heavy, sag ich Dir.

      Natuerlich steht in meinem originellen Perlscript in diesem Teil des Programs kein Kommentar. Der Kommentar habe ich nur fuer
      die Leser eingefuegt. Trotzdem geht es nicht.

      Vielleicht probierst Du einmal ein Perl-Modul aus, welches Dir vielleicht helfen kann. HTML-Tree z.B.
      XML-Module könnten vielleicht auch helfen, ist nur so eine Idee.

      Leider habe ich mit den Modulen noch nie gearbeitet.

      Entschuldigen fuer eventuell viele Fehler. Ich bin Ausländer.

      MfG, Lev Benenson