Schrift
[thread]10448[/thread]

Mit perl einen "wide character" ausfindig machen

Leser: 5


<< >> 4 Einträge, 1 Seite
smallish
 2007-09-24 00:10
#99900 #99900
User since
2005-10-13
28 Artikel
BenutzerIn
[default_avatar]
Mein Problem ist es, dass ich gerne etwas auslesen möchte und dass dann in eine Datei speichern, die ich dann weiter verwenden will. Nun befindet sich in dem Teil den ich einlesen, offensichtlich ein "wide character".

Ich möchte nun diesen in ein normales Zeichen umwandeln und muss in dazu zuerst einmal erkennen. Kann Perl mir selbstständig erkennen bei welchem der Zeichen es sich um einen "wide character" handelt?

Grüsse
sid burn
 2007-09-24 00:27
#99901 #99901
User since
2006-03-29
1520 Artikel
BenutzerIn

user image
Möchtest du nur die Fehlermeldung weg bekommen?

Diese Fehlermeldung kommt eigentlich nur dann wenn du in einer Variablen UTF8 Codierte Daten gespeichert hast, und diese Variable dann z.B. einfach mit print ausgiebst.

Perl selber versuchst dann nämlich die Zeichen umzukonvertieren nach iso-8859-1. Wenn es aber ein Unicode Zeichen ist das in iso-8859-1 nicht vokommt kann er nicht konvertieren und es kommt die gesagte Fehlermeldung.

Wenn du aber UTF8 Daten hast und möchtest sie wirklich auch nur ausgeben ohne Fehlermeldung solltest du lediglich mit binmode STDOUT z.B. auf UTF8 setzen, das geht so:
Code (perl): (dl )
binmode STDOUT, ':utf8'


Wenn du natürlich ein anderes Filehandle nutzt musst du natürlich anstatt STDOUT dein genutzes Filehandle hinschreiben. Danach gibt er auch UTF8 Daten ohne die Fehlermeldung aus.


Wenn du eine Datei zum Lesen öffnest das utf8 codiert ist solltest du auch sichergehen das du die Datei folgendermaßen öffnest:
Code (perl): (dl )
open my $fh, '<:utf8', 'utf8file.txt'  or  die $!


Wenn du UTF8 Daten in einem Filehandle schreibst solltest du die Datei entweder so öffnen.
Code (perl): (dl )
open my $fh, '>:utf8', 'utf8file.txt'  or  die $!

oder wenn du nicht '>:utf8' schreibst mit binmode das Filehandle auf utf8 setzen
Code (perl): (dl )
binmode $fh, ':utf8'


Danach kommen auch keine Fehlermeldungen mehr.
Nicht mehr aktiv. Bei Kontakt: ICQ: 404181669 E-Mail: perl@david-raab.de
smallish
 2007-09-24 00:48
#99907 #99907
User since
2005-10-13
28 Artikel
BenutzerIn
[default_avatar]
Danke für deine Antwort.

Bei meinem Problem handelte es sich um ein simples -, das von Hand von einer Internetseite in ein Textfenster von Tk hineinkopiert wurde. Nun habe ich folgendes gemacht: Mit ord() herausgefunden, welches Zeichen gemeint ist (8211). Das Zeichen mit s/char(8211)/-/ ersetzt, damit sich das Zeichen nicht in ein ? verwandelt. Und speichere nun alles mit encode("iso-8859-1", $inhalt) in eine Datei.

Funktioniert prächtig! :D

PS: Wahrscheinlich nicht die feine englische Art, so wie deine Lösung. Wenn ich jedoch mit utf8 in eine Datei schreibe, muss ich sie immer über Perl oder ein anderes Programm, das utf8 versteht gebrauchen und das wollte ich nicht.
ptk
 2007-09-24 23:09
#99948 #99948
User since
2003-11-28
3645 Artikel
ModeratorIn
[default_avatar]
Wenn du eine allgemeine Lösung möchtest, kannst du CPAN:Text::Unidecode verwenden. Damit können alle Unicode-Zeichen in ASCII-Pendant umgewandelt werden. Mit der Funktion unten kann man das Modul auch verwenden, um statt nach ASCII in ein beliebiges Encoding zu wandeln.

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
50
51
52
53
54
55
56
=head2 unidecode_any($text, $encoding)

Similar to Text::Unidecode::unidecode, but convert to the given
$encoding. This will return an octet string in the given I<$encoding>.
If all you want is just to restrict the charset of the string to a
specific encoding charset, then it's best to C<Encode::decode> the
result again with I<$encoding>.

=cut

sub unidecode_any {
    my($text, $encoding) = @_;

    require Text::Unidecode;
    require Encode;

    # provide better conversions for german umlauts
    my %override = ("\xc4" => "Ae",
                    "\xd6" => "Oe",
                    "\xdc" => "Ue",
                    "\xe4" => "ae",
                    "\xf6" => "oe",
                    "\xfc" => "ue",
                   );
    my $override_rx = "(" . join("|", map { quotemeta } keys %override) . ")";
    $override_rx = qr{$override_rx};

    my $res = "";

    if (!eval {
        Encode->VERSION(2.12); # need v2.12 to support coderef
        $res = Encode::encode($encoding, $text,
                              sub {
                                  my $ch = chr $_[0];
                                  if ($ch =~ $override_rx) {
                                      return $override{$ch};
                                  } else {
                                      my $ascii = unidecode($ch);
                                      Encode::_utf8_off($ascii);
                                      $ascii;
                                  }
                              });
        1;
    }) {
        for (split //, $text) {
            my $conv = eval { Encode::encode($encoding, $_, Encode::FB_CROAK()) };
            if ($@) {
                $res .= Text::Unidecode::unidecode($_);
            } else {
                $res .= $conv;
            }
        }
    }

    $res;
}
<< >> 4 Einträge, 1 Seite



View all threads created 2007-09-24 00:10.