2010-07-24 5 views
0

Je rencontre des problèmes avec les caractères Unicode en Perl. Lorsque je reçois des données depuis le Web, j'obtiens souvent des caractères comme √¢¬Ä¬ú ou √¢¬Ç¬¨. Le premier est un guillemet et le second est le symbole de l'euro. Maintenant je peux facilement substituer les bonnes valeurs en Perl et imprimer les mots corrigés à l'écran, mais quand j'essaie de sortir un fichier .CSV toutes les substitutions que j'ai faites sont pour rien et je reçois des ordures dans mon Fichier .CSV. (Les citations fonctionnent, devinant puisque c'est un caractère si général). Aussi Numéro donnera Numéro. Les exemples sont infinis.Perl Text :: Problèmes de codage CSV_XS

J'ai écrit un petit programme pour essayer de comprendre ce problème, mais je ne sais pas quel est le problème. J'ai lu sur un autre thread de débordement de pile que vous pouvez importer le .CSV dans Excel et choisir l'encodage UTF8, cette option ne s'affiche pas pour moi cependant. Je me demande si je peux juste l'encoder dans n'importe quel jeu de caractères natif d'Excel (UTF16BE ???), ou s'il y a une autre solution. J'ai essayé beaucoup de variations sur ce programme court, et permettez-moi de dire qu'il est juste pour tester les problèmes Unicode, pas une partie d'un programme légitime. Merci.

use strict; 
use warnings; 
require Text::CSV_XS; 
use Encode qw/encode decode/; 

my $text = 'Numéro Numéro Numéro Orkos Capital SAS (√¢¬Ä¬úOrkos√¢¬Ä¬ù) 325M√¢¬Ç¬¨ in 40 companies headquartered'; 

print("$text\n\n\n"); 

$text =~ s/“|”/"/sig; 
$text =~ s/’s/'s/sig; 
$text =~ s/√¢¬Ç¬¨/€/sig; 
$text =~ s/√¢¬Ñ¬¢/®/sig; 
$text =~ s/ / /sig; 

print("$text\n\n\n"); 

my $CSV = Text::CSV_XS->new ({ binary => 1, eol => "\n" }) or die "Cannot use CSV: ".Text::CSV->error_diag(); 

open my $OUTPUT, ">:encoding(utf8)", "unicode.csv" or die "unicode.csv: $!"; 

my @row = ($text); 

$CSV->print($OUTPUT, \@row); 
$OUTPUT->autoflush(1); 

J'ai aussi essayé ces deux lignes en vain:

$text = decode("Guess", $text); 
$text = encode("UTF-16BE", $text); 

Répondre

0

J'ai donc trouvé la réponse, le commentaire de Roland Illig m'a aidé à y arriver (merci encore!). Décoder plus d'une fois provoque l'erreur de caractères larges, et ne devrait donc pas être fait.

La clé ici est de décoder le texte UTF-8, puis de le coder dans MacRoman. Pour envoyer les fichiers .CSV à mes amis Windows, je dois d'abord les enregistrer sous .XLSX afin que le codage ne soit pas encore tout à fait effrayant.

 
$text =~ s/“|”/"/sig; 
$text =~ s/’s/'s/sig; 
$text =~ s/√¢¬Ç¬¨/€/sig; 
$text =~ s/√¢¬Ñ¬¢/®/sig; 
$text =~ s/ / /sig; 

$text = decode("UTF-8", $text); 

print("$text\n\n\n"); 

my $CSV = Text::CSV_XS->new ({ binary => 1, eol => "\n" }) or die "Cannot use CSV: ".Text::CSV->error_diag(); 

open my $OUTPUT, ">:encoding(MacRoman)", "unicode.csv" or die "unicode.csv: $!"; 
1

Tout d'abord, vos chaînes sont encodées dans MacRoman. Lorsque vous les interprétez comme des séquences d'octets, la seconde donne C3 A2 C2 82 C2 AC. Cela ressemble à UTF-8 et la forme décodée est E2 82 AC. Cela ressemble à nouveau à UTF-8, et lorsque vous le décodez, vous obtenez . Donc ce que vous devez faire est:

$step1 = decode("MacRoman", $text); 
$step2 = decode("UTF-8", $step1); 
$step3 = decode("UTF-8", $step2); 

Ne me demandez pas sur quelles voies mystérieuses ce codage a été créé en premier lieu. Votre premier personnage décode comme U+201C, qui est en effet le LEFT DOUBLE QUOTATION MARK.

Note: Si vous êtes sur un Mac, la première étape de décodage peut être inutile puisque le codage est seulement dans la « couche de présentation » (lorsque vous avez copié la source Perl dans le formulaire HTML et votre navigateur fait l'encodage -translation pour vous) et pas dans les données elles-mêmes.

+0

Lorsque je tente ce que j'obtiens l'erreur suivante: Impossible de décoder la chaîne avec de larges caractères à la ligne /Library/Perl/Updates/5.10.0/darwin-thread-multi-2level/Encode.pm 174. Qu'entend-on par "caractères larges" ?? Aussi, je suis sur un Mac. – user387049

+0

Habituellement, lorsque vous «décodez» quelque chose, vous passez d'une séquence d'octets à une séquence de caractères. Le message d'erreur "Wide Characters" vous indique que vous avez déjà une séquence de caractères. C'est un filet de sécurité qui vous empêche de faire des choses que vous ne voulez pas normalement. –

+0

Peut-être que cela vous aide si vous enregistrez votre programme Perl non pas dans l'encodage MacRoman mais en UTF-8. Ou faites-vous déjà cela? –