如何在 ActiveState Perl 中获取正确的非 ASCII 命令行参数?

发布于 2024-12-11 05:47:35 字数 478 浏览 0 评论 0原文

使用 ActiveState Perl v5.14.2 在 Windows 7 cmd 窗口上运行以下命令

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

会产生以下结果:

97
223
63
100
101
63

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

Running the following command

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

on a Windows 7 cmd window with ActiveState Perl v5.14.2 produces the following result:

97
223
63
100
101
63

The above values are nonsensical and don't correspond to any known encoding, so trying to decode them with the approach recommended in
How can I treat command-line arguments as UTF-8 in Perl? doesn't help. Changing the command window active code page doesn't change the results.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

乖乖兔^ω^ 2024-12-18 05:47:35

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

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

注意 cp1252 不能代表所有这些字符,这就是为什么控制台和 Perl 实际上收到

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

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

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

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

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

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

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

请注意,使用 chcp 修改控制台窗口中使用的代码页不会影响 Perl 接收其参数的代码页,该代码页始终是 ANSI 代码页。请参阅下面的示例(cp737 是希腊语 OEM 代码页,cp1253 是希腊语 < a href="http://en.wikipedia.org/wiki/Windows_code_page#ANSI_code_page" rel="nofollow">ANSI 代码页。 本文档中的 37 和 M7。)

C:\>chcp 737
Active code page: 737

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

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

C:\>chcp 1253
Active code page: 1253

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

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

Your system, like every Windows system I know, uses by default the 1252 ANSI code page, so you could try to use

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

Note that cp1252 cannot represent all of those characters, which is why the console and thus Perl actually receives

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

There is a "Wide" interface for passing (almost) any Unicode code point to a program, but

  1. The Wide interface is not used when you type in a command at the prompt.
  2. Perl uses the ANSI interface to fetch the parameters, so even if you started Perl using the Wide interface, the parameters would get downgraded to ANSI when Perl fetches them.

Sorry, but this is a "you can't" type of situation. You need a different approach. Diomidis Spinellis suggests changing your system's ANSI code page as follows in Win7:

  1. Control Panel
  2. Region and Language
  3. Administrative
  4. Language for non-Unicode programs
  5. Set the Current language for non-Unicode programs to the language associated with the specific characters (Greek in your case).

At this point, you'd use the encoding of the ANSI code page associated with the new selected encoding instead of cp1252 (cp1253 for Greek).

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

Note that using chcp to modify the code page used within the console window does not affect the code page in which Perl receives its arguments, which is always an ANSI code page. See the examples below (cp737 is the Greek OEM code page, and cp1253 is the Greek ANSI code page. You can find the encodings labeled as 37 and M7 in this document.)

C:\>chcp 737
Active code page: 737

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

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

C:\>chcp 1253
Active code page: 1253

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

C:\>perl -e "print map sprintf('%x ', ord($_)), split(//, $ARGV[0])" αβγδεζ
e1 e2 e3 e4 e5 e6
孤者何惧 2024-12-18 05:47:35

这对我有用(在 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}; }"

那是针对 STDIN 的;对于 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#命令开关

This worked for me (on OS-X, but should be portable):

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

That was for STDIN; for ARGV:

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

See the -C option in perlrun: http://perldoc.perl.org/perlrun.html#Command-Switches

相对绾红妆 2024-12-18 05:47:35

如果我将字符放入文件中(来自 OS-X),将其复制到 Windows 盒子(如 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 语言环境。

If I place the characters in a file (from OS-X), copy it to a windows box (as file.txt), then run:

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

Then I get the expected:

946
947
948
949
950

But if I copy the contents of file.txt to the command line, I get gibberish.

As @ikegami was saying, I don't think it's possible to do from command line since you don't have a UTF-8 locale.

逆光飞翔i 2024-12-18 05:47:35

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

You could try using https://metacpan.org/pod/Win32::Unicode::Native. It should have what you need.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文