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

Kar*_*lee 6 windows perl character-encoding

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

当我调用另一个Perl代码- test2.pltest1.pl无论是system(..)Win32::Process,环境自带乱码.

有人可以提供信息,为什么会这样,以及解决它的方法?

perl我使用的版本是5.8.

如果我的理解是正确的,在perl内部使用utf-8,那么初始过程 - test1.plWindows-1252→ 收到它utf-8.当我们调用另一个进程时,我们应该转换回Windows-1252代码页吗?

dax*_*xim 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";
Run Code Online (Sandbox Code Playgroud)

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;
Run Code Online (Sandbox Code Playgroud)

执行:

> set TEST=abc£
> B:\sperl\perl\bin\perl.exe B:\test1.pl
Run Code Online (Sandbox Code Playgroud)

输出(缩短):

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}"]
Run Code Online (Sandbox Code Playgroud)

Windows使用与文本环境(IBM850)不同的编码而不是图形环境(Windows-1252)这一事实让您感到痛苦.专家必须解释这种现象的更深层细节.

编辑:

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

有一些方法可以隐含地解码外部数据,例如openpragma/IO层-C交换机,但它们只处理文件流和程序参数.截至目前,必须从环境中明确解码.无论如何,我更喜欢那样,明确表示你已经考虑过主题的维护程序员.