Schrift
Wiki:Tipp zum Debugging: use Data::Dumper; local $Data::Dumper::Useqq = 1; print Dumper \@var;
[thread]10457[/thread]

DER richtige Zeichensatz ... (Windows, Linux, ...)

Leser: 1


<< >> 7 Einträge, 1 Seite
Hagen
 2007-09-24 18:20
#99932 #99932
User since
2007-09-06
233 Artikel
BenutzerIn
[default_avatar]
Hallo,

mittlerweile dürfen/müssen meine eigenen Perl-Scripte nicht nur auf meinem einem Rechner unter Linux/Ubuntu laufen, sonder auch noch unter Windows (div. Versionen) und Unix und sollen/müssen dort Daten verarbeiten.

Bei den Daten handelt es sich entweder um kurze Benutzereingabe, (eher häufig) um CSV-Dateien die mit unterschiedlicher Software (OO, MS Office, Notepad, ...) erstellt wurden oder um Interent-Seiten. Mit Hilfe des Perl-Scriptes werden (häufig) wieder Daten in Form von Text-Dateien (z.B. TeX-Dateien) erstellt.

Durch die unterschiedlichen Systeme kommt es häufiger zum Problemen bei Umlauten (warum ist klar, durch die unterschiedlichen Zeichensätze). Aber wie gehe ich mit dem Problem am besten um ... da fehlt mir ein Konzept. Schließlich will ich nicht für jedes System das Perl-Script anpassen (müssen).

Es ist schwer bzw. nicht möglich zu sagen, dass Daten nur UTF8-Kodiert an das Script geliefert werden.
Gruß
Hagen
Taulmarill
 2007-09-24 18:45
#99933 #99933
User since
2004-02-19
1750 Artikel
BenutzerIn

user image
Also, pauschal zu erkennen um welche Codierung es sich bei einer Textdatei handelt ist schwierig. Du solltest dich mit deinen Datenlieferanten besprechen und diese dazu überreden, dass sie entweder Ihre Daten auf irgend eine Weise markieren oder dass über eine bestimmte Schnittstelle immer nur die selbe Codierung kommt. Zum ändern der Codierung kannst du das Core-Modul Encode benutzen.
$_=unpack"B*",~pack"H*",$_ and y&1|0& |#&&print"$_\n"for@.=qw BFA2F7C39139F45F78
0A28104594444504400 0A2F107D54447DE7800 0A2110453444450500 73CF1045138445F4800 0
F3EF2044E3D17DE 8A08A0451412411 F3CF207DF41C79E 820A20451412414 83E93C4513D17D2B
AndreasM
 2007-09-24 21:38
#99941 #99941
User since
2005-10-08
31 Artikel
BenutzerIn
[Homepage] [default_avatar]
Evtl. ist auch das hier hilfreich:
http://search.cpan.org/~jgmyers/Encode-Detect-0.01...

Grüße
AndreasM
ptk
 2007-09-24 23:56
#99954 #99954
User since
2003-11-28
3645 Artikel
ModeratorIn
[default_avatar]
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];
}
Hagen
 2007-09-25 12:19
#99965 #99965
User since
2007-09-06
233 Artikel
BenutzerIn
[default_avatar]
Taulmarill+2007-09-24 16:45:32--
... Du solltest dich mit deinen Datenlieferanten besprechen und diese dazu überreden, dass sie entweder Ihre Daten auf irgend eine Weise markieren ...


Könntest du mal erklären, was du genau mit "markieren" meinst ... oder einfach 'nur' schreiben das es utf-8, ... ist?

Taulmarill+2007-09-24 16:45:32--
... Zum ändern der Codierung kannst du das Core-Modul Encode benutzen. ...


Werde ich mir mal genauer durchlesen, danke!

Das/mein Problem ist, dass der Datenlieferant eher ein DAU ist und daher von Zeichensätzen keine Ahnung hat .... bin auch gerade erst dabei mich einzulesen.
Gruß
Hagen
Taulmarill
 2007-09-25 12:27
#99966 #99966
User since
2004-02-19
1750 Artikel
BenutzerIn

user image
Mit "markieren" meine ich eine beliebige Methode, mit der der Datenlieferant die Daten um die Information ergänzt, um welche Codierung es sich handelt. Das kann z.b. ein Teil des Dateinamens sein oder einfach in der ersten Zeile stehen. An eine bestimmte Methode hatte ich nicht gedacht. Was am sinnvollsten ist, hängt von den Rahmenbedingungen ab.

Quote
... mein Problem ist, dass der Datenlieferant eher ein DAU ist ...

Das ist natürlich suboptimal (aka scheiße). Ich denke hier ist Kreativität auf deiner Seite gefragt. Schau dir an, wie die Daten erzeugt werden. Evtl. kann man da ansetzen und eine Vorgehensweise erarbeiten, die dir immer das selbe Format garantiert.
$_=unpack"B*",~pack"H*",$_ and y&1|0& |#&&print"$_\n"for@.=qw BFA2F7C39139F45F78
0A28104594444504400 0A2F107D54447DE7800 0A2110453444450500 73CF1045138445F4800 0
F3EF2044E3D17DE 8A08A0451412411 F3CF207DF41C79E 820A20451412414 83E93C4513D17D2B
Hagen
 2007-10-02 19:00
#100223 #100223
User since
2007-09-06
233 Artikel
BenutzerIn
[default_avatar]
Danke für die Hinweise und Idee. Dann werde wohl mal ein bisschen Kreativität in die Lösung stecken müssen.

Obwohl ich gedacht hätte, dass es sich eher um ein schon älteres Problem handeln würde. Schließlich laufen Perl-Scripte weltweit auf sehr unterschiedlichen Servern zur Vearbeitung von sehr unterschiedlichen Daten (z.B. Gästebuch auf einer Homepage).

Taulmarill+2007-09-25 10:27:36--
Mit "markieren" meine ich eine beliebige Methode, mit der der Datenlieferant die Daten um die Information ergänzt, um welche Codierung es sich handelt. Das kann z.b. ein Teil des Dateinamens sein oder einfach in der ersten Zeile stehen. An eine bestimmte Methode hatte ich nicht gedacht. Was am sinnvollsten ist, hängt von den Rahmenbedingungen ab.


Bei den Daten handelt es sich um reine CSV-Dateien. Man könnte sicherlich einen Test-String am Anfang oder Ende einfügen. Die Lösung finde ich aber nicht so optimal. Ebenfalls die Lösung mit dem Dateinamen finde ich nicht so toll, inbesondere wenn es über die Grenzen des (eigenen) Betriebssystems hinaus geht.

Quote
Schau dir an, wie die Daten erzeugt werden. Evtl. kann man da ansetzen und eine Vorgehensweise erarbeiten, die dir immer das selbe Format garantiert.


Wäre ein Ansatz.

In den CSV-Dateien sind eigentlich nur 'normale' Zeichen zugelassen (a-z, 0-9 und ein paar Symbole ), d.h. keine Steuerzeichen. D.h. wenn ich diese rausfiltern würde, dürften nur noch Problemzeichen übrig bleiben, die dann entsprechend ersetzt werden (also der Ansatz von ptk). Mal probieren, ob mir das reich.
Gruß
Hagen
<< >> 7 Einträge, 1 Seite



View all threads created 2007-09-24 18:20.