2

运行以下命令

perl -e "for (my $i = 0; $i < length($ARGV[0]); $i++) {print ord(substr($ARGV[0], $i, 1)), qq{\n}; }" αβγδεζ

在带有 ActiveState Perl v5.14.2 的 Windows 7 cmd 窗口上产生以下结果:

97
223
63
100
101
63

上面的值是无意义的,并且不对应于任何已知的编码,因此尝试使用 如何在 Perl 中将命令行参数视为 UTF-8 中推荐的方法对其进行解码?没有帮助。更改命令窗口活动代码页不会更改结果。

4

4 回答 4

3

你的系统,就像我知道的每个 Windows 系统一样,默认使用 1252 ANSI 代码页,所以你可以尝试使用

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

请注意,cp1252 不能代表所有这些字符,这就是控制台和 Perl 实际接收的原因

  • 97
  • ß 223
  • ? 63
  • d 100
  • 101
  • ? 63

有一个“宽”接口用于将(几乎)任何 Unicode 代码点传递给程序,但是

  1. 当您在提示符处键入命令时,不使用 Wide 界面。
  2. Perl 使用 ANSI 接口来获取参数,因此即使您使用 Wide 接口启动 Perl,当 Perl 获取参数时,参数也会降级为 ANSI。

抱歉,这是一种“你不能”的情况。你需要一种不同的方法。Diomidis Spinellis 建议在 Win7 中更改系统的 ANSI 代码页,如下所示:

  1. 控制面板
  2. 地区和语言
  3. 行政的
  4. 非 Unicode 程序的语言
  5. 将非 Unicode 程序的当前语言设置为与特定字符关联的语言(在您的情况下为希腊语)。

此时,您将使用与新选择的编码相关联的 ANSI 代码页的编码,而不是cp1252(cp1253表示希腊语)。

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

请注意,chcp用于修改控制台窗口中使用的代码页不会影响 Perl 接收其参数的代码页,它始终是 ANSI 代码页。请参阅下面的示例(cp737 是希腊OEM 代码页,cp1253 是希腊ANSI 代码页。您可以在本文档中找到标记为 37 和 M7 的编码。)

C:\>chcp 737
活动代码页:737

C:\>回波αβγδεζ | od -t x1
0000000 98 99 9a 9b 9c 9d 20 0d 0a

C:\>perl -e "打印映射 sprintf('%x', ord($_)), split(//, $ARGV[0])" αβγδεζ
e1 e2 e3 e4 e5 e6

C:\>chcp 1253
活动代码页:1253

C:\>回波αβγδεζ | od -t x1
0000000 e1 e2 e3 e4 e5 e6 20 0d 0a

C:\>perl -e "打印映射 sprintf('%x', ord($_)), split(//, $ARGV[0])" αβγδεζ
e1 e2 e3 e4 e5 e6
于 2011-10-19T17:53:36.487 回答
0

如果我将字符放在文件中(来自 OS-X),将其复制到 Windows 框(as file.txt),然后运行:

perl -CI -e "chomp($_=<STDIN>); map{print ord, qq{\n}} split(//)" < file.txt

然后我得到了预期:

946
947
948
949
950

但是,如果我将 的内容复制file.txt到命令行,就会出现乱码。

正如@ikegami 所说,我认为不可能从命令行执行,因为您没有 UTF-8 语言环境。

于 2011-10-19T18:10:55.987 回答
0

您可以尝试使用https://metacpan.org/pod/Win32::Unicode::Native。它应该有你需要的东西。

于 2011-10-20T09:41:48.530 回答
0

这对我有用(在 OS-X 上,但应该是可移植的):

echo  αβγδεζ |perl -CI -e "chomp($in=<STDIN>);for (my $i = 0; $i < length($in); $i++) {print ord(substr($in, $i, 1)), qq{\n}; }"

那是针对标准输入的;对于 ARGV:

perl -CA -e "for (my $i = 0; $i < length($ARGV[0]); $i++) {print ord(substr($ARGV[0], $i, 1)), qq{\n}; }" αβγδεζ

查看 perlrun 中的-C选项:http: //perldoc.perl.org/perlrun.html#Command-Switches

于 2011-10-19T16:34:42.650 回答