如何在Perl中将命令行参数视为UTF-8?
如何在Perl中将如何在Perl中将命令行参数视为UTF-8?,perl,unicode,utf-8,Perl,Unicode,Utf 8,如何在Perl中将@ARGV的元素视为UTF-8 目前我正在使用以下解决方法 use Encode qw(decode encode); my $foo = $ARGV[0]; $foo = decode("utf-8", $foo); 。。它可以工作,但不是很优雅 我使用的是PerlV5.8.8,它是从BashV3.2.25调用的,LANG设置为en_US.UTF-8。您不必对字符串做任何特殊的处理。Perl字符串默认为UTF-8格式,从Perl 5.8开始 perl -CO -le 'p
@ARGV
的元素视为UTF-8
目前我正在使用以下解决方法
use Encode qw(decode encode);
my $foo = $ARGV[0];
$foo = decode("utf-8", $foo);
。。它可以工作,但不是很优雅
我使用的是PerlV5.8.8,它是从BashV3.2.25调用的,LANG设置为en_US.UTF-8。您不必对字符串做任何特殊的处理。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上运行良好
假乙烯基灌木提出了一个很好的观点,我们可以看到两者之间的明确区别
perl -Mutf8 -wle ';print utf8::is_utf8($ARGV[0]) ? "t" : "f"' a
及
你这样做似乎是对的。这就是我要做的
但是,这表明命令行标志
-CA
应该告诉它将@ARGV
视为utf-8。(未经测试)。外部数据源在Perl中很棘手。对于命令行参数,您可能会将其作为您的区域设置中指定的编码。不要依赖您的区域设置与可能运行您的程序的其他人相同
您必须找出它是什么,然后将其转换为Perl的内部格式。幸运的是,这并不难
模块提供了获取编码所需的内容:
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
我发现“如果你知道”是一个很大的危险信号,实际上意味着“我们不确定”。使用:
这也适用于Win32,对我来说很好。例如windows
设置代码
在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
其中,尽管命令行参数不是以Perl字符串的形式出现的。它和其他任何东西一样是一个外部数据源。但是如果他或她的shell设置为UTF-8,那么他或她键入的任何东西都将是UTF-8。我发现指定工作环境比覆盖所有可能的环境更容易。现在,如果这意味着要分发给其他人,这会改变情况,但问题是终端将被设置为UTF-8。类似地,大多数情况下,我不会处理
文件::Spec
,即使我的代码在某些系统上无法工作。-CA希望命令行参数编码为UTF-8。这并不意味着他们是。:)谢谢你提供的信息,所以你是说这种方式假设UTF-8编码,但是你的方式去发现编码…?我发现假设任何编码都是不安全的。太多的人让它在他们的机器上工作,然后发现它为其他具有不同设置的人中断。请注意,这在脚本中不起作用,即您不能执行#/usr/bin/perl-CA
。或者至少我下载的一个脚本失败了。只是一个细微的nit:ARGV本身通常表示名为ARGV的文件句柄。对于@ARGV(保存命令行参数的数组),答案有点不同。:)我这个答案的问题是I18N::Langinfo在Win32上不可用(即使它在corelist中!)。我的perl(5.18.0,Mac OS X 10.8)返回US-ASCII(以$codeset为单位),即使我的终端设置为unicode(UTF-8)。如果我手动将$codeset设置为UTF-8,则decode()会起作用。这将为我在v5.18和X.8中返回UTF-8
:$perl5.18.0-MI18N::Langinfo=Langinfo,code-set-E'say Langinfo(code-set)
。你确定你的设置正确吗?你在哪个版本的perl中找到了Encode::Locale
?我已经有了v5.10.1版本,尝试使用Encode::Locale
会导致找不到模块:(它不在core中,您可以在cpan或您的软件包管理器上安装它。
chcp 1251
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