[Moscow.pm] кодировка в Perl почему все это так странно работает?
Nikolay Mishin
mi на ya.ru
Вт Сен 23 13:09:18 PDT 2014
там есть шикарная функция
Encode::Locale::decode_argv();
все уменьшилось до
#!/usr/bin/env perl
use utf8;
use Modern::Perl;
use Encode::Locale qw(decode_argv);
if (-t)
{
binmode(STDIN, ":encoding(console_in)");
binmode(STDOUT, ":encoding(console_out)");
binmode(STDERR, ":encoding(console_out)");
}
Encode::Locale::decode_argv();
my $lang = shift or die "Usage: $0 What_is_your_language?\n";
$lang =~ /
(perl|перл)
(?{print "use Perl or die!!\nИспользуй Перл или умри!!";})
/ix;
https://github.com/mishin/presentation/blob/master/100_regex_4_moscow_pm.pl
23.09.2014, 23:52, "Nikolay Mishin" <mi на ya.ru>:
> Здравствуйте, Илья
> добавил
> $lang = decode(locale => $lang);
> удалив все лишнее, вы просто супер!!
> https://github.com/mishin/presentation/blob/master/100_regex_4_moscow_pm.pl
> а код модуля говорит сам за себя
>
> if ($^O eq "MSWin32") {
> unless ($ENCODING_LOCALE) {
> # Try to obtain what the Windows ANSI code page is
> eval {
> unless (defined &GetACP) {
> require Win32::API;
> Win32::API->Import('kernel32', 'int GetACP()');
> };
> if (defined &GetACP) {
> my $cp = GetACP();
> $ENCODING_LOCALE = "cp$cp" if $cp;
> }
> };
> }
>
> 23.09.2014, 13:15, "Илья Винокуров" <ilvin на mail.ru>:
>> Здравствуйте, Николай!
>>
>> Вы используете 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
>> ,
>>
>> --
>> 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