bitmuncher
Senior-Nerd
Ich bin gerade dabei mit Perl einen Parser zu schreiben, der Dateien einliest und daraus spezielle Informationen extrahiert. Unter anderem steht in den Dateien auch ein Charset. Um an das Charset zu kommen nutze ich
Und hier kommt das Problem in's Spiel. Die Dateien enthalten nämlich manchmal mehrere Charset-Informationen, von denen ich nur 2 Formate benötige und die 3 verschiedene Formate haben können. Hier mal die möglichen Formate:
und zu guter Letzt können HTML-Sachen in den Dateien sein, die dann etwa wie folgt ausssehen:
wobei bei dieser letzten Variante das Meta-Tag manchmal in einer Zeile steht und manchmal auf mehrere Zeilen verteilt ist. Ich benötige allerdings nur die ersten beiden Varianten.
Vor dem raussuchen des Charsets dekodiere ich natürlich das quoted-printabe-Format mit
so dass das Meta-Tag danach in ISO vorliegt (bzw. vorliegen sollte
). Hat jemand eine effektive Lösung ohne tausende Überprüfungen (idealerweise mit 1-2 Regexen), wie ich das Charsets des HTML-Tags ausschliessen kann? Das Problem liegt für mich hier darin, daß das Meta-Tag auf mehrere Zeilen verteilt sein kann, aber nicht muß und daß ich die Dateien zeilenweise einlese (while($line = <FILE>)...). Das Programm "weiß" daher nicht immer, ob in der Zeile davor ein Meta-Tag begonnen hat, wenn der Abschnitt 'charset="ISO-8859-1"' am Anfang der Zeile steht. Falls jemand auch nur den Ansatz einer Idee hat, dann immer her damit. Mit einem Schalter habe ich es auch schon versucht, der einfach auf 1 gesetzt wurde, wenn in einer Zeile ein HTML-Meta-Tag gefunden wurde, allerdings kann nach dem HTML-Code durchaus auch ein Charset enthalten sein, das ich noch benötige, was dann natürlich durch das gesetzte Flag geflissentlich ignoriert wurde.
Code:
if($line =~ m/charset/i) {
$line =~ m/charset=(.*)/i;
$charset = $1;
if($charset =~ m/^\"/i) {
$charset =~ m/\"(.*)\"/i;
$charset = $1;
}
print "Charset: $charset\n";
}
Und hier kommt das Problem in's Spiel. Die Dateien enthalten nämlich manchmal mehrere Charset-Informationen, von denen ich nur 2 Formate benötige und die 3 verschiedene Formate haben können. Hier mal die möglichen Formate:
Code:
Content-Type: text/plain;
charset="iso-8859-1"
Code:
Content-Type: text/plain;charset=ISO-8859-1
bzw.
Content-Type: text/html;charset=ISO-8859-1
und zu guter Letzt können HTML-Sachen in den Dateien sein, die dann etwa wie folgt ausssehen:
Code:
<meta http-equiv=3D"Content-Type" content=3D=
"text/html; charset=3DISO-8859-1">
wobei bei dieser letzten Variante das Meta-Tag manchmal in einer Zeile steht und manchmal auf mehrere Zeilen verteilt ist. Ich benötige allerdings nur die ersten beiden Varianten.
Vor dem raussuchen des Charsets dekodiere ich natürlich das quoted-printabe-Format mit
Code:
my $res = shift;
$res =~ s/\r\n/\n/g;
$res =~ s/[ \t]+\n/\n/g;
$res =~ s/=\n//g;
if (ord('A') == 193) {
if (ord('[') == 173) {
$res =~ s/=([\da-fA-F]{2})/Encode::encode('cp1047',Encode::decode('iso-8859-1',pack("C", hex($1))))/ge;
}
elsif (ord('[') == 187) {
$res =~ s/=([\da-fA-F]{2})/Encode::encode('posix-bc',Encode::decode('iso-8859-1',pack("C", hex($1))))/ge;
}
elsif (ord('[') == 186) {
$res =~ s/=([\da-fA-F]{2})/Encode::encode('cp37',Encode::decode('iso-8859-1',pack("C", hex($1))))/ge;
}
}
else { # ASCII style machine
$res =~ s/=([\da-fA-F]{2})/pack("C", hex($1))/ge;
}
$res;
so dass das Meta-Tag danach in ISO vorliegt (bzw. vorliegen sollte