Как строки perl представлены внутренне? Какая кодировка используется? Как правильно обрабатывать разные кодировки?
Я использую Perl довольно долгое время, но он не включал много обработки строк в разных кодировках, и когда я столкнулся с небольшой проблемой, связанной с кодировками, я обычно прибегал к некоторому шаманскому действия.
До этого момента я думал о строках perl как о последовательностях байтов, которые вполне подходили для моих задач. Теперь мне нужно выполнить некоторую обработку файла в кодировке UTF-8, и тут начинаются проблемы.
Сначала я читаю файл в строку так:
open(my $in, '<', $ARGV[0]) or die "cannot open file $ARGV[0] for reading";
binmode($in, ':utf8');
my $contents;
{
local $/;
$contents = <$in>;
}
close($in);
, затем просто распечатайте его:
print $contents;
И я получаю две вещи: предупреждение Wide character in print at <scriptname> line <n>
и мусор в консоли. Таким образом, я могу заключить, что строки perl имеют понятие «символ», которое может быть «широким» или нет, но при печати эти «широкие» символы представляются в консоли в виде нескольких байтов, а не в виде одного «символа».
(Теперь мне интересно, почему весь мой предыдущий опыт работы с бинарными файлами работал так, как я ожидал, что он будет работать без каких-либо «символических» проблем).
Почему тогда я вижу мусор в консоли? Если Perl хранит строки в виде символов в некоторой известной кодировке, я не думаю, что есть большая проблема, чтобы выяснить кодировку консоли и правильно распечатать текст. (Я использую Windows, кстати).
Если Perl хранит строки в виде символьных последовательностей переменной ширины (например, используя ту же кодировку UTF-8), почему это делается так? По моему опыту C, обработка строк - PAIN.
Обновление .
Я использую два компьютера для тестирования, один из которых работает под управлением Windows 7 x64 с установленным английским языковым пакетом, но с русскими региональными настройками (поэтому у меня cp866 как OEM-кодовая страница и cp1251 как ANSI) с ActivePerl 5.10.1 x64; другая работает под управлением Windows XP 32-битная русская локализация с Cygwin Perl 5.10.0.
Благодаря ссылкам, теперь у меня гораздо более четкое понимание того, что происходит и как это сделать.