[Moscow.pm] кодировка в Perl почему все это так странно работает?
Илья Винокуров
ilvin на mail.ru
Вт Сен 23 02:15:17 PDT 2014
Здравствуйте, Николай!
Вы используете Console::Locale.
Почитайте документацию https://metacpan.org/pod/Encode::Locale
Из нее вы поймете, что этот модуль определяет кодировку консоли
более точно, чем детекторы.
Если для STDIN, STDERR, STDOUT вы сделали телодвижения по
автоматической перекодировке, то для @ARGV ничего не сделано,
поэтому разумно использовать:
my $lang = decode( locale => $ARGV [0]);
А детекторы кодировок - это зло, существующее из-за безнадеги...
С почтением,
Илья Винокуров.
Mon, 22 Sep 2014 23:58:07 +0400 от Nikolay Mishin <mi на ya.ru>:
>Илья, привет , удалил Text::Iconv
>-my $converter = Text::Iconv->new( "cp1251", "utf-8");
>-$lang = $converter->convert($lang);
>+Encode::from_to($lang, 'windows-1251', 'utf-8');
>https://github.com/mishin/presentation/commit/2d1ba8adcfc451d45454490b5bf442f95bd41e0a
>и все заработало,
>правда получается, что кодировка , которую Encode::Detect::Detector
>определяет как ISO-8859-7 является одновременно и кодировкой windows-1251,
>странно, что больше этого нигде не написано, в общем парадоксальное решение,
>чисто перебором
>
>22.09.2014, 12:51, "Илья Винокуров" < ilvin на mail.ru >:
>> Здравствуйте, Николай.
>>
>> Внутри Perl строки хранятся в кодировке, совместимой с UTF-8. Эта кодировка называется utf8.
>> Когда строки вводятся в Perl, их нужно декодировать из различных кодировок в utf8.
>> В том числе нужно декодировать UTF-8 в utf8.
>> Если строку нужно вывести из Perl, то эту строку нужно кодировать в различные кодировки.
>> В том числе нужно кодировать utf8 в UTF-8
>>
>> Этим занимаются функции 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 mailing list
>moscow-pm на pm.org | http://moscow.pm.org
>
----------- следущая часть -----------
Вложение в формате HTML было извлечено…
URL: <http://mail.pm.org/pipermail/moscow-pm/attachments/20140923/95d8d3ab/attachment.html>
Подробная информация о списке рассылки Moscow-pm