Thread DER richtige Zeichensatz ... (Windows, Linux, ...)
(6 answers)
Opened by Hagen at 2007-09-24 18:20
Ich hätte einen etwas anderen Ansatz zu bieten. Man kann ihn verwenden, wenn man weiß, welche Zeichen man in den zu analysierenden Texten erwarten kann. Also wenn man weiß, dass z.B. man nur deutsche Texte analysieren muss, kann man annehmen, dass nur die Unicode-Codepoints bis 127, die Umlaute, vielleicht noch das Euro-Symbol und "deutsche" Apostrophe vorkommen (im Skript unten: @expected_codepoints). Dann weiß man vielleicht, welche Encodings überhaupt vorkommen (unten: @expected_encodings). Wenn nicht, werden einfach alle Encodings ausprobiert, die Perl kennt. Zuletzt kommt der zu analysierende Text, natürlich in Octets ausgedrückt (unten: $octets_to_analyze). Das Skript gibt dann die Reihenfolge der Encodings mit der Prozentzahl, wie gut der Text zu diesem Encoding passt.
Code (perl): (dl
)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 # Which are the expected Unicode codepoints? my @expected_codepoints = (9, 10, 13, # newlines+tab 32..127, (map { ord } split //, "äöüÄÖÜß"), 0x20ac, # euro sign ); # Which are the expected encodings? May be empty, in this case # all to perl available encodings will be checked. my @expected_encodings = qw(cp1252 iso-8859-1 utf-8); # Text to analyze, specify in raw octets: my $octets_to_analyze = "Bla äöü \x80"; ###################################################################### # No user-servicable parts below this point. use strict; use Encode; if (!@expected_encodings) { @expected_encodings = Encode->encodings(":all"); } my %expected_codepoints = map {($_,1)} @expected_codepoints; my @encoding_result; for my $encoding (@expected_encodings) { my $characters = eval { decode($encoding, $octets_to_analyze, Encode::FB_CROAK|Encode::LEAVE_SRC); }; if (!$@) { my %got_codepoints; for my $codepoint (map { ord } split //, $characters) { $got_codepoints{$codepoint}++; } my $fitting_codepoints = 0; while(my($k,$v) = each %got_codepoints) { if (exists $expected_codepoints{$k}) { $fitting_codepoints++; } } push @encoding_result, [$encoding, $fitting_codepoints*100/keys %got_codepoints]; } } @encoding_result = sort { $b->[1] <=> $a->[1] } @encoding_result; for my $result (@encoding_result) { printf "%-30s: %4.1f%%\n", $result->[0], $result->[1]; } |