Perl Text :: CSV_XS Проблемы с кодировкой - PullRequest
0 голосов
/ 25 июля 2010

У меня проблемы с символами Юникода в Perl.Когда я получаю данные из Интернета, я часто получаю такие символы, как √¢¬Ä¬ú или √¢¬Ç¬¨.Первый - это кавычка, а второй - символ евро.

Теперь я могу легко подставить правильные значения в Perl и вывести на экран исправленные слова, но когда я пытаюсь вывести в файл .CSV все подстановки, которые я произвел, ничего не происходит, и я получаю мусорв моем .CSV файле.(Цитаты работают, догадываясь, потому что это такой общий характер).Также Numéro даст Numéro.Примеры бесконечны.

Я написал небольшую программу, чтобы попытаться выяснить эту проблему, но я не уверен, в чем проблема.Я прочитал в другом потоке переполнения стека, что вы можете импортировать .CSV в Excel и выбрать кодировку UTF8, хотя эта опция не появляется для меня.Мне интересно, могу ли я просто закодировать его в какой-либо родной набор символов Excel (UTF16BE ???) или есть другое решение.Я пробовал много вариантов этой короткой программы, и позвольте мне еще раз сказать, что она предназначена только для тестирования проблем Unicode, а не является частью легальной программы.Спасибо.

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);

Я также пробовал эти две строки безрезультатно:

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

Ответы [ 2 ]

1 голос
/ 25 июля 2010

Во-первых, ваши строки закодированы в MacRoman.Когда вы интерпретируете их как последовательности байтов, второе приводит к C3 A2 C2 82 C2 AC.Это похоже на UTF-8, а декодированная форма - E2 82 AC.Это снова выглядит как UTF-8, и когда вы его декодируете, вы получаете .Итак, что вам нужно сделать, это:

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

Не спрашивайте меня, какими загадочными способами была создана эта кодировка в первую очередь.Ваш первый символ декодируется как U+201C, что на самом деле является LEFT DOUBLE QUOTATION MARK.

Примечание: Если вы работаете на Mac, первый шаг декодирования может быть ненужным, поскольку кодированиев «уровне представления» (когда вы скопировали исходный код Perl в форму HTML и ваш браузер выполнил кодировку-перевод для вас), а не в самих данных.

0 голосов
/ 25 июля 2010

Так что я разобрался с ответом, комментарий от Роланда Иллига помог мне туда добраться (еще раз спасибо!).Декодирование более одного раза вызывает ошибку широких символов, и поэтому не должно выполняться.

Ключевым моментом здесь является декодирование текста UTF-8, а затем кодирование его в MacRoman.Чтобы отправить файлы .CSV моим друзьям из Windows, я должен сначала сохранить их как .XLSX, чтобы кодирование снова не испортилось.

$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: $!";
...