2011-03-19 62 views
7

我有一個Perl和Encoding雜注的問題。Perl的使用編碼雜注破壞UTF字符串

(我使用UTF-8無處不在,輸入,輸出,Perl腳本自己。我不希望使用其他的編碼,永遠。)

不過。當我寫

binmode(STDOUT, ':utf8'); 
use utf8; 
$r = "\x{ed}"; 
print $r; 

我看到字符串「í」(這是我想要什麼 - 什麼是U + 00ED的Unicode字符)。但是當我添加這樣的「使用編碼」雜注

binmode(STDOUT, ':utf8'); 
use utf8; 
use encoding 'utf8'; 
$r = "\x{ed}"; 
print $r; 

我看到的只是一個盒子角色。爲什麼?

而且,當我添加數據::自卸車,讓自卸車打印新的字符串,這樣

binmode(STDOUT, ':utf8'); 
use utf8; 
use encoding 'utf8'; 
$r = "\x{ed}"; 
use Data::Dumper; 
print Dumper($r); 

我看到的Perl 改變字符串"\x{fffd}"。爲什麼?

+1

另請參閱:http://stackoverflow.com/questions/492838/why-do-my-perl-tests-fail-with-use-encoding-utf8 – 2011-03-19 16:09:26

回答

9

use encoding 'utf8'壞了。它不是將\x{ed}解釋爲代碼點U + 00ED,而是將其解釋爲單個字節237,然後嘗試將其解釋爲UTF-8。當然哪一個失敗了,所以最後用替換字符U + FFFD代替它,字面意思是「 」。

只要堅持use utf8以指定您的源文件使用UTF-8和binmodeopen pragma來指定文件句柄的編碼。

+0

哦......好的。我不能聲稱我理解重新解釋的原因,但是在perl中有很多更奇怪的東西。謝謝 – 2011-03-19 16:16:46

+3

據我所知,原因是'使用編碼'是爲了讓人們可以編寫'使用編碼'euc-jp'; $ r =「\ xF1 \ xD1 \ xF1 \ xCC」;'並將其解釋爲「正確」。但是這意味着你必須以相同的風格編寫你的UTF-8字符串,例如'$ r =「\ xC3 \ xAD」;'。與Perl的本地支持UTF-8相結合,例如'$ r =「\ x {200b}」;然而,與代碼0x80-0xff的轉義解釋與代碼0x100及更高的轉義不同。 – Anomie 2011-03-19 16:20:03

+3

是的,Perl對8位語言環境的支持('use encoding','use locale')應該保存在一個很長的棒的另一端。 – hobbs 2011-03-19 17:08:38

5

您的實際代碼既不需要use encoding也不需要use utf8即可正常運行 - 唯一依賴的是STDOUT上的編碼層。

binmode(STDOUT, ":utf8"); 
print "\xed"; 

是一個同樣有效的完整程序,可以做你想做的。

use utf8只有在程序中的字面字符串中包含UTF-8時才應使用 - 例如,如果你這樣寫

my $r = "í"; 

然後use utf8將導致該字符串被解釋爲單個字符U + 00ED,而不是一系列字節C3 AD的。

use encoding不應該被使用,尤其是被喜歡Unicode的人使用。如果你想要改變stdin/out的編碼,你應該使用-CPERLUNICODE或者自己對它們進行binmode,如果你想讓其他的句柄自動被編碼層打開,你應該使用useopen

+0

hobbs:是的,我在我的代碼中使用了實際的UTF-8文字(正則表達式)。謝謝。 – 2011-03-19 16:41:34