如何在Perl中正确使用编码为Windows-1251的环境变量?

时间:2010-03-13 09:39:10

标签: windows perl character-encoding

我在Windows中设置了一个环境变量TEST=abc£,它使用Windows-1252代码页。现在,当我运行Perl程序test.pl时,此环境值正确。

当我通过test2.pltest1.plsystem(..)调用另一个Perl代码 - Win32::Process时,环境会出现乱码。

有人可以提供信息,为什么会这样解决?

我使用的perl版本是5.8。

如果我的理解是正确的,perl内部使用utf-8,那么初始流程 - test1.pl就会从Windows-1252utf-8收到。当我们调用另一个进程时,我们是否应该转换回Windows-1252代码页?

1 个答案:

答案 0 :(得分:9)

这与Perl的内部字符串编码无关,但需要正确解码来自外部的数据。我将提供测试用例。这是西欧Windows XP上的Strawberry Perl 5.10。

test1.pl:

use Devel::Peek;
print Dump $ENV{TEST};
use Encode qw(decode);
my $var = decode 'Windows-1252', $ENV{TEST};
print Dump $var;

system "B:/sperl/perl/bin/perl.exe B:/test2.pl";

test2.pl:

use Devel::Peek;
print Dump $ENV{TEST};
use Encode qw(decode);
my $var = decode 'IBM850', $ENV{TEST};
# using Windows-1252 again is wrong here
print Dump $var;

执行:

> set TEST=abc£
> B:\sperl\perl\bin\perl.exe B:\test1.pl

输出(缩短):

SV = PVMG(0x982314) at 0x989a24
  FLAGS = (SMG, RMG, POK, pPOK)
  PV = 0x98de0c "abc\243"\0
SV = PV(0x3d6a64) at 0x989b04
  FLAGS = (PADMY, POK, pPOK, UTF8)
  PV = 0x9b5be4 "abc\302\243"\0 [UTF8 "abc\x{a3}"]
SV = PVMG(0x982314) at 0x989a24
  FLAGS = (SMG, RMG, POK, pPOK)
  PV = 0x98de0c "abc\243"\0
SV = PV(0x3d6a4c) at 0x989b04
  FLAGS = (PADMY, POK, pPOK, UTF8)
  PV = 0x9b587c "abc\302\243"\0 [UTF8 "abc\x{a3}"]

Windows会对文本环境(IBM850)使用与图形环境(Windows-1252)不同的编码这一事实而感到困惑。专家必须解释这一现象的更深层细节。

编辑:

有可能启发式(意味着它有时会做不正确的事,特别是对于这样的短字符串)确定编码。最佳通用解决方案是Encode::Detect/Encode::Detect::Detector,它基于Mozilla nsUniversalDetector

有一些方法可以隐含地解码外部数据,例如open pragma/IO layers-C switch,但它们只处理文件流和程序参数。截至目前,必须从环境中明确解码。无论如何,我更喜欢那样,明确表示你认为topic通过的维护程序员。