Matching Operator (Perl sucht nicht die spitzen Klammern)
Lev Benenson
- perl
0 Michael Schröpl0 klaus
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
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
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);
- 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.
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