2016-10-06 3 views
1

Я пытаюсь получить Юникода в качестве аргументов в PERL скрипт:Perl поддержка юникода из консоли (@ARGV)/Windows/

C:\>perl test.pl ö 

#---- 
# test.pl 
#---- 
#!/usr/bin/perl 
use warnings; 
use strict; 

my ($name, $number) = @ARGV; 

if (not defined $name) { 
    die "Need name\n"; 
} 

if (defined $number) { 
    print "Save '$name' and '$number'\n"; 
    # save name/number in database 
    exit; 
} 

if ($name eq 'ö') { 
    print "Fetch umlaut 'oe'\n"; 
} elsif ($name eq 'o') { 
    print "Fetch simple 'o'\n"; 
} else { 
    print "Fetch other '$name'\n"; 
} 

print "ü"; 

и я получаю результат:

Fetch simple 'o' 
ü 

I 'протестировал код (алгоритм) в python 3, и он работает, поэтому я получаю «ö». Но, очевидно, в perl есть что-то большее, что я должен добавить или установить. Не имеет значения, это Strawberry Perl или ActiveState Perl. Я получаю тот же результат.

Заранее благодарен!

ответ

4
#!/usr/bin/perl 

use strict; 
use warnings; 

my $encoding_in; 
my $encoding_out; 
my $encoding_sys; 
BEGIN { 
    require Win32; 

    $encoding_in = 'cp' . Win32::GetConsoleCP(); 
    $encoding_out = 'cp' . Win32::GetConsoleOutputCP(); 
    $encoding_sys = 'cp' . Win32::GetACP(); 

    binmode(STDIN, ":encoding($encoding_in)"); 
    binmode(STDOUT, ":encoding($encoding_out)"); 
    binmode(STDERR, ":encoding($encoding_out)"); 
} 

use Encode qw(decode); 

{ 
    my ($name, $number) = map { decode($encoding_sys, $_) } @ARGV; 

    if (not defined $name) { 
     die "Need name\n"; 
    } 

    if (defined $number) { 
     print "Save '$name' and '$number'\n"; 
     # save name/number in database 
     exit; 
    } 

    if ($name eq 'ö') { 
     print "Fetch umlaut 'oe'\n"; 
    } elsif ($name eq 'o') { 
     print "Fetch simple 'o'\n"; 
    } else { 
     print "Fetch other '$name'\n"; 
    } 

    print "ü"; 
} 

Кроме того, вы должны добавить use feature qw(unicode_strings); и/или кодировать файл, используя UTF-8 и добавить use utf8;.

+0

У вас есть мнение относительно 'Encode :: Locale'? Кажется, он заменяет несколько строк кода, которые у вас есть. – tjd

+0

@tjd, Похоже, вы действительно можете это использовать. Не стесняйтесь публиковать ответ, и я буду продвигать и, возможно, даже удалить мой! – ikegami

+0

Это не работает. Я получаю только Fetch simple 'o' ü Очевидно, что он автоматически анализирует «ö» на «o». Это perl 5, версия 24, subversion 0 (v5.24.0), созданная для MSWin32-x64-multi-thread. – Banish

3

В дополнение к тонкому ответу ikagami, я являюсь поклонником модуля Encode::Locale, который автоматически создает псевдонимы для кодовых страниц текущей консоли. Он отлично работает с Win32, OS X & другими вкусами * nix.

#!/usr/bin/perl 

use strict; 
use warnings; 

# These two lines make life better when you leave the world of ASCII 
# Just remember to *save* the file as UTF8.... 
use utf8; 
use feature 'unicode_strings'; 

use Encode::Locale 'decode_argv';   # We'll use the console_in & console_out aliases as well as decode_argv(). 
use Encode; 

binmode(STDIN, ":encoding(console_in)"); 
binmode(STDOUT, ":encoding(console_out)"); 
binmode(STDERR, ":encoding(console_out)"); 

decode_argv(); # Decode ARGV in place 
my ($name, $number) = @ARGV; 

if (not defined $name) { 
    die "Need name\n"; 
} 

if (defined $number) { 
    print "Save '$name' and '$number'\n"; 
    # save name/number in database 
    exit; 
} 

if ($name eq 'ö') { 
    print "Fetch umlaut 'oe'\n"; 
} elsif ($name eq 'o') { 
    print "Fetch simple 'o'\n"; 
} else { 
    print "Fetch other '$name'\n"; 
} 

print "ü"; 

Возможно, это только синтаксический сахар, но он облегчает чтение и способствует кросс-платформенной совместимости.

+0

Неопределенная подпрограмма & main :: decode_argv вызывается в vidCmpr2.pl строка 18. – Banish

+0

@Banish Вы правы. Я забыл импортировать этот символ в строку использования. Спасибо за напоминание. – tjd

+0

Да, мне пришлось импортировать пакет. Теперь он успешно компилируется, но это все. Я протестировал его, изменив кодовую страницу консоли (chcp 1252) или даже с perl6. Он анализирует «ö» как простой «o». Python и java анализируют его без проблем. – Banish

Смежные вопросы