Как я могу рассматривать аргументы командной строки как UTF-8 в Perl?
Как обрабатывать элементы @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.
Ответы
Ответ 1
Внешние источники данных сложны в 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
Я нахожу "если вы знаете", что это большой красный флаг, который действительно означает "мы не уверены".
Ответ 2
Используйте Encode :: Locale:
use Encode::Locale;
decode_argv Encode::FB_CROAK;
Это работает, также на Win32, довольно хорошо для меня.
Ответ 3
То, как вы это сделали, кажется правильным. Это то, что я буду делать.
Однако, эта perldoc страница предполагает, что флаг командной строки -CA
должен сказать, что он обрабатывает @ARGV
как utf-8. (не проверено).
Ответ 4
Например, для окон
set code
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
Ответ 5
Вам не нужно делать ничего особенного для строки. 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