Perl использует кодировку прагмы, ломая строки UTF - PullRequest
7 голосов
/ 19 марта 2011

У меня проблема с прагмой Perl и Encoding.

(я использую utf-8 везде, при вводе, выводе, сами скрипты perl. Я не хочу использовать другую кодировку, никогда.)

Тем не менее. Когда я пишу

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

Я вижу строку " í " (это то, что я хочу - и что такое U + 00ED unicode char) Но когда я добавляю прагму «использовать кодировку», как это

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

все, что я вижу, это символ коробки. Почему?

Более того, когда я добавляю Data :: Dumper и позволяю Dumper напечатать новую строку, как это

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

Я вижу, что perl изменил строку на "\x{fffd}". Почему?

Ответы [ 2 ]

9 голосов
/ 19 марта 2011

use encoding 'utf8' сломан. Вместо того, чтобы интерпретировать \x{ed} как кодовую точку U + 00ED, он интерпретирует его как один байт 237 и затем пытается интерпретировать это как UTF-8. Что, конечно, не получается, так что в итоге он заменяется символом замены U + FFFD, буквально « ».

Просто наберите use utf8, чтобы указать, что ваш источник находится в UTF-8, и binmode или open pragma , чтобы указать кодировку для файловых дескрипторов.

5 голосов
/ 19 марта 2011

Ваш настоящий код не нуждается ни в use encoding, ни use utf8 для правильной работы - от него зависит только уровень кодирования на STDOUT.

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

- в равной степени действительная полная программа, которая делает то, что вы хотите.

use utf8 следует использовать только в том случае, если в вашей программе есть UTF-8 в литеральных строках - например, если бы вы написали

my $r = "í";

затем use utf8 приведет к тому, что эта строка будет интерпретирована как один символ U + 00ED вместо серии байтов C3 AD.

use encoding никогда не должен использоваться, особенно тем, кто любит Юникод. Если вы хотите, чтобы кодировка stdin / out была изменена, вы должны использовать -C или PERLUNICODE или их бинмодирование самостоятельно, а если вы хотите, чтобы другие маркеры автоматически открывались слоями кодирования, вам следует useopen.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...