там есть шикарная функция
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" <[email protected]>:
> Здравствуйте, Илья
> добавил
> $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, "Илья Винокуров" <[email protected]>:
>>  Здравствуйте, Николай!
>>
>>  Вы используете 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 <[email protected]>:
>>>  Илья, привет , удалил 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, "Илья Винокуров" <[email protected]>:
>>>>   Здравствуйте, Николай.
>>>>
>>>>   Внутри 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 <[email protected]>:
>>>>>   Привет, 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
>>>>>  [email protected] | http://moscow.pm.org
>>>>   ,
>>>>
>>>>   --
>>>>   Moscow.pm mailing list
>>>>  [email protected] | http://moscow.pm.org
>>>  --
>>>  С уважением
>>>  Николай Мишин
>>>  --
>>>  Moscow.pm mailing list
>>>  [email protected] | http://moscow.pm.org
>>  ,
>>
>>  --
>>  Moscow.pm mailing list
>>  [email protected] | http://moscow.pm.org
>
> --
> С уважением
> Николай Мишин
>
> --
> Moscow.pm mailing list
> [email protected] | http://moscow.pm.org

-- 
С уважением
Николай Мишин

-- 
Moscow.pm mailing list
[email protected] | http://moscow.pm.org

Ответить