2010-07-24 172 views
0

我在Perl中遇到Unicode字符問題。當我從網上收到數據時,我經常會看到像√¢¬Ä¬ú√¢¬Ç¬¨這樣的字符。第一個是引號,第二個是歐元符號。Perl Text :: CSV_XS編碼問題

現在我可以很容易地用Perl中的正確值替換,並在屏幕上打印正確的單詞,但是當我嘗試輸出到.CSV文件時,我所做的所有替換都是無用的, .CSV文件。 (引號工作,猜測,因爲它是一個普通的字符)。 Numéro也會給Numéro。這些例子是無止境的。

我寫了一個小程序來試圖解決這個問題,但我不確定問題是什麼。我讀過另一個堆棧溢出線程,您可以在Excel中導入.CSV並選擇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); 

回答

0

所以我想出了答案,來自Roland Illig的評論幫助我到達那裏(再次感謝!)。解碼不止一次會導致寬字符錯誤,因此不應該這樣做。

這裏的關鍵是解碼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: $!"; 
1

首先,你的字符串在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

當我嘗試這一點,我得到以下錯誤: 不能/Library/Perl/Updates/5.10.0/darwin-thread-multi-2level/Encode.pm線174解碼字符串寬字符。 什麼是「寬字符」?另外我在Mac上。 – user387049 2010-07-24 21:22:54

+0

通常,當你對某些東西進行解碼時,你會從一個字節序列到一個字符序列。 「寬字符」錯誤消息告訴你,你已經有一個字符序列。這是一個安全網,阻止你做你通常不想做的事情。 – 2010-07-24 22:01:20

+0

如果你不是在MacRoman編碼中保存你的Perl程序,而是在UTF-8中保存你的Perl程序,它可能會有所幫助。或者你已經這樣做了? – 2010-07-24 22:03:10