Как я могу рассматривать аргументы командной строки как UTF-8 в Perl? - PullRequest
17 голосов
/ 10 января 2010

Как мне обращаться с элементами @ARGV как UTF-8 в Perl?

В настоящее время я использую следующий обходной путь ..

use Encode qw(decode encode);

my $foo = $ARGV[0];
$foo = decode("utf-8", $foo);

.. который работает, но не очень элегантно.

Я использую Perl v5.8.8, который вызывается из bash v3.2.25 с LANG, установленным в en_US.UTF-8.

Ответы [ 5 ]

29 голосов
/ 10 января 2010

Внешние источники данных являются сложными в Perl. Для аргументов командной строки вы, вероятно, получаете их в виде кодировки, указанной в вашей локали. Не надейтесь, что ваш язык будет таким же, как у кого-то, кто может запустить вашу программу.

Вы должны выяснить, что же тогда конвертировать во внутренний формат Perl. К счастью, это не так сложно.

В модуле I18N :: Langinfo есть то, что нужно для получения кодировки:

    use I18N::Langinfo qw(langinfo CODESET);
    my $codeset = langinfo(CODESET);

Как только вы знаете кодировку, вы можете декодировать их в строки Perl:

    use Encode qw(decode);
    @ARGV = map { decode $codeset, $_ } @ARGV;

Хотя Perl кодирует внутренние строки как UTF-8, вы никогда не должны думать об этом или знать об этом. Вы просто декодируете все, что получаете, что превращает это во внутреннее представление Perl для вас. Поверьте, что Perl справится со всем остальным. Когда вам нужно сохранить данные, убедитесь, что вы используете нужную кодировку.

Если вы знаете, что ваша установка UTF-8, и терминал выдаст вам аргументы командной строки как UTF-8, вы можете использовать опцию A с переключателем Perl -C. Это говорит вашей программе, что аргументы должны быть закодированы как UTF-8:

% perl -CA program

Вы также получаете это только с -C, который включает несколько других опций Unicode:

% perl -C program

Я нахожу "если вы знаете" большой красный флаг, который на самом деле означает "мы не уверены", однако.

8 голосов
/ 13 сентября 2012

Использовать Кодировать :: Язык :

use Encode::Locale;

decode_argv Encode::FB_CROAK;

Это работает, также на Win32, довольно хорошо для меня.

4 голосов
/ 10 января 2010

То, как вы это сделали, кажется правильным. Вот что я бы сделал.

Однако, эта perldoc страница предполагает, что флаг командной строки -CA должен указывать ему @ARGV как utf-8. (не проверено).

1 голос
/ 19 июня 2015

Например для окон код набора

chcp 1251

в 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();

в командной строке

perl -C ppixregexplain.pl qr/\bмама\b/i > ex1.html 2>&1  

где ppixregexplain.pl

0 голосов
/ 10 января 2010

Вам не нужно делать ничего особенного со строкой. Строки Perl по умолчанию в UTF-8, начиная с Perl 5.8.

perl -CO -le 'print "\x{2603}"' | xargs perl -le 'print "I saw @ARGV"'

Приведенный выше код прекрасно работает на Ubuntu 9.04, OS X 10.6 и FreeBSD 7.

FalseVinylShrub поднимает хороший вопрос, мы можем увидеть определенную разницу между

perl -Mutf8 -wle ';print utf8::is_utf8($ARGV[0]) ? "t" : "f"' a

и

perl -Mutf8 -CA -wle ';print utf8::is_utf8($ARGV[0]) ? "t" : "f"' a
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...