Если я запустил следующую программу Perl:
perl -e 'use utf8; print "鸡\n";'
Я получаю это предупреждение:
Wide character in print at -e line 1.
Если я запустил эту программу Perl:
perl -e 'print "鸡\n";'
Я не получаю предупреждения.
Я думал, что use utf8
необходимо использовать символы UTF-8 в Perl-скрипте. Почему это не работает и как это исправить? Я использую Perl 5.16.2. У меня такая же проблема, если это находится в файле, а не в командной строке.
Ответы:
Без
use utf8
Perl интерпретирует вашу строку как последовательность однобайтовых символов. Как видно из этого, в вашей строке четыре байта:$ perl -E 'say join ":", map { ord } split //, "鸡\n";' 233:184:161:10
Первые три байта составляют ваш символ, последний - перевод строки.
Вызов to
print
отправляет эти четыре символа в STDOUT. Затем ваша консоль решает, как отображать эти символы. Если ваша консоль настроена на использование UTF8, она будет интерпретировать эти три байта как ваш единственный символ, и это то, что отображается.Если мы добавим
utf8
модуль, все будет иначе. В этом случае Perl интерпретирует вашу строку как всего два символа.$ perl -Mutf8 -E 'say join ":", map { ord } split //, "鸡\n";' 40481:10
По умолчанию уровень ввода-вывода Perl предполагает, что он работает с однобайтовыми символами. Поэтому, когда вы пытаетесь напечатать многобайтовый символ, Perl думает, что что-то не так, и выдает предупреждение. Как всегда, вы можете получить более подробное объяснение этой ошибки, включив
use diagnostics
. Он скажет так:Как указывали другие, вам нужно указать Perl, чтобы он принимал многобайтовый вывод. Есть много способов сделать это (см. Некоторые примеры в Perl Unicode Tutorial ). Один из самых простых способов - использовать
-CS
флаг командной строки, который сообщает трем стандартным дескрипторам файлов (STDIN, STDOUT и STDERR) работать с UTF8.$ perl -Mutf8 -e 'print "鸡\n";' Wide character in print at -e line 1. 鸡
против
$ perl -Mutf8 -CS -e 'print "鸡\n";' 鸡
Юникод - это большая и сложная область. Как вы видели, кажется, что многие простые программы поступают правильно, но по неправильным причинам. Когда вы начинаете исправлять часть программы, все становится еще хуже, пока вы не исправите всю программу.
источник
-Mutf8
если не в одном лайнере perl?use utf8;
Все
use utf8;
это говорит Perl о том, что исходный код закодирован с использованием UTF-8. Вам нужно указать Perl, как кодировать ваш текст:use open ':std', ':encoding(UTF-8)';
источник
Кодируйте весь стандартный вывод как UTF-8:
binmode STDOUT, ":utf8";
источник
use open ':std', ':encoding(UTF-8)';
как предлагается другим ответом, делает это для STDOUT, но также отмечает STDERR и STDIN как UTF-8, поэтому вы получаете три по цене одного оператора. См. Также stackoverflow.com/a/42194059Вы можете приблизиться к «просто используйте utf8 везде», используя модуль CPAN
utf8::all
.perl -Mutf8::all -e 'print "鸡\n";'
Когда он
print
получает что-то, что он не может напечатать (символ больше 255, если:encoding
слой не предоставлен), он предполагает, что вы хотели кодировать его с помощью UTF-8. Он делает это после предупреждения о проблеме.источник
Вы можете использовать это,
Это также устранит эту ошибку.
источник
На испанском языке вы можете найти эту ошибку, когда не начнете использовать:
use utf8;
Кодировка вашего редактора имеет другую кодировку. Итак, то, что вы видите в редакторе, не то, что делает Perl. Чтобы решить эту ошибку, просто измените кодировку редактора на Unicode / UTF-8 .
источник