请注意下面的 ã
如何更改为 a
。注意 2:在将此归咎于 CMD.EXE 和 Windows 管道怪异之前,请参阅下面的实验 2,该实验使用 File::Find 会遇到类似的问题。
我试图解决的特定问题涉及处理存储在本地驱动器上的图像文件,以及操作可能包含外来字符的文件名。下面显示的两个实验是中间调试步骤。
ã
字符在拉丁语言中很常见。例如 http://pt.wikipedia.org/wiki/Cão
实验1
仔细观察,注意cão
如何变成cao
。
实验2
这里我尝试使用 File::Find 而不是管道输入,以防问题出在 |
shell 操作符的 Windows 实现上。当 ~a
变成 Pi
时,问题实际上变得更糟:
调试更新:
我尝试了http://perldoc.perl.org/perlunicode.html中列出的一些技巧。 ,
例如使用utf8
,使用功能'unicode_strings'
等,但无济于事。
环境和版本信息
操作系统是 Windows 7,64 位。
Perl 是:
This is perl 5, version 12, subversion 2 (v5.12.2) built for MSWin32-x64-multi-thread
(with 8 registered patches, see perl -V for more detail)
Copyright 1987-2010, Larry Wall
Binary build 1202 [293621] provided by ActiveState http://www.ActiveState.com
Built Sep 6 2010 22:53:42
最佳答案
Perl 与许多其他脚本语言一样,是构建在 C 运行时之上的。
在 Windows 上,窄(字节)字符的标准 MS C 运行时使用默认为 Windows 系统编码(“ANSI 代码页”)进行 IO 事件(例如打开文件或写入控制台)的编码。
ANSI 代码页始终是特定于区域设置的编码:通常是单字节,但在某些区域设置(例如中国、日本等)中是多字节。它绝不是 UTF-8 或任何其他能够复制整个 Unicode 的东西; Perl IO 可以处理哪些字符取决于 Windows 区域设置(“非 Unicode 程序的语言”设置)。
虽然可以使用 chcp 65001 命令为控制台应用程序提供 UTF-8,但这样做会出现许多严重的不一致问题。这给 Windows 上的很多工具带来了困难,微软确实需要解决这个问题,但到目前为止他们的态度是 Unicode 等于 UTF-16;每个想要 Unicode 工作的人都必须使用 Widechar 接口(interface)。
因此,您当前无法在 Windows 上的 Perl 中可靠地处理使用非 ASCII 文件名的文件。抱歉。
您可以尝试使用 Python(它在 2.3 版及以后版本中添加了特殊的仅适用于 Windows 的文件名处理来解决此问题;请参阅 PEP 277),或一种支持 Unicode 的 Windows 脚本宿主语言。不管怎样,在 Windows 上将 Unicode 输出到控制台仍然存在更多陷阱。
关于perl - 为什么 Perl 在 Windows 上会丢失外来字符?这个问题可以解决吗(如果可以,如何解决)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4527182/