[Moscow.pm] кодировка в Perl почему все это так странно работает?

Victor Efimov victor на vsespb.ru
Пн Сен 22 01:58:13 PDT 2014


22 сентября 2014 г., 12:51 пользователь Илья Винокуров <ilvin на mail.ru> написал:
> Здравствуйте, Николай.
>
> Внутри Perl строки хранятся в кодировке, совместимой с UTF-8. Эта кодировка
> называется utf8.
> Когда строки вводятся в Perl, их нужно декодировать из различных кодировок в
> utf8.
> В том числе нужно декодировать UTF-8 в utf8.
> Если строку нужно вывести из Perl, то эту строку нужно кодировать в
> различные кодировки.
> В том числе нужно кодировать utf8 в UTF-8
>

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

В perl строки не храянятся как набор абстрактных символов. Рассуждения
про их кодировку лучше присекать на корню.
Отличия между utf8 и UTF-8 - вовсе не в этом, а в том что utf-8 более
строкая валидация чем utf8.

Но в остальном, если в тексте выше заменить "utf8" на "символьная
строка", то будет ок.

> Этим занимаются функции Encode::encode('UTF-8', $string) и
> Encode::decode('UTF-8', $string).
>
> Text::Iconv - не используйте это, если точно не знаете почему вам нужен
> именно этот модуль.
>
> Концепцию работы с кодировками в Perl я рассказал,
> а вот свой скрипт поправить потрудитесь сами пожалуйста...
>
> PS: Чтобы не возиться в явном виде с перекодированием строк, в перл
> используют
>
>     binmode STDIN,  ":encoding(console_in)"  if -t STDIN;
>     binmode STDOUT, ":encoding(console_out)" if -t STDOUT;
>     binmode STDERR, ":encoding(console_out)" if -t STDERR;
>
> После этого в STDIN/STDOUT можно читать/писать строки в кодировке utf8 без
> перекодирования...
>
> С почтением,
>   Илья Винокуров.
>
> Mon, 22 Sep 2014 01:28:15 +0400 от Nikolay Mishin <mi на ya.ru>:
>
> Привет, MoscowPM,
> тут родился вопрос под win7 (юникс могут быть теже странности, не проверял)
>
> #!/usr/bin/env perl
> use utf8;
> use Modern::Perl;
> use Encode::Locale;
> use Encode qw( decode encode from_to);
> use Text::Iconv;
> use Encode::Detect::Detector;
> use Data::Dumper qw( Dumper );
>
>
> if (-t)
> {
>     binmode(STDIN, ":encoding(console_in)");
> binmode(STDOUT, ":encoding(console_out)");
> binmode(STDERR, ":encoding(console_out)");
> }
>
> my $lang = shift or die "Usage: $0 What_is_your_language?\n";
> my_dump('lang_01',$lang);
> my $converter = Text::Iconv->new( "cp1251", "utf-8");
> $lang = $converter->convert($lang);
> my_dump('lang_02',$lang);
> $lang = Encode::decode("utf8",$lang);
> my_dump('lang_03',$lang);
> my_dump('lang_04_перл',qq{перл});
>
>  $lang =~ /(perl|перл) (?{print "use Perl or die!!\nИспользуй Перл или
> умри!!";}) /ix;#русский не мачится, почему?
>
>  sub my_dump
>  {
>  my ($name,$var)=@_;
>  local $Data::Dumper::Useqq = 1;
>  local $Data::Dumper::Indent = 0;
>  local $Data::Dumper::Terse = 1;
>  print(Encode::Detect::Detector::detect(qq{$lang})." ".qq{\$$name }."
> dump=".Dumper($var)."\n");
>  }
>
> этот же код на гитхабе
> https://github.com/mishin/presentation/blob/master/100_regex_4_moscow_pm.pl
>
> моя задача была, чтобы скрипт
> perl 100_regex_4_moscow_pm.pl перл
> читая из консоли слово "перл" находил его в регексе внутри скрипта
>
> вопросы:
> 1) почему, если в консоле
> perl -MEncode::Detect::Detector -E "say
> Encode::Detect::Detector::detect(qq{перл})"
> у меня кодировка ISO-8859-7
> my $converter = Text::Iconv->new( "cp1251", "utf-8");
> Text::Iconv ее проглатывает как cp1251 (причем ISO там не проходит) ?
>
> 2)что происходит со строкой здесь
> UTF-8 $lang_02 dump="\320\277\320\265\321\200\320\273"
> $lang = Encode::decode("utf8",$lang);
> UTF-8 $lang_03 dump="\x{43f}\x{435}\x{440}\x{43b}"
> --что такое делает decode?
> я так понимаю - он починивает utf8, но что конкретно
>
> спасибо, хорошей недели!!
>
>
> --
> С уважением
> Николай Мишин
>
> --
> Moscow.pm mailing list
> moscow-pm на pm.org | http://moscow.pm.org
>
>
>
> --
> Moscow.pm mailing list
> moscow-pm на pm.org | http://moscow.pm.org
>


Подробная информация о списке рассылки Moscow-pm