我已经使用perl很长一段时间了,但它不包括很多字符串处理不同的编码,当我遇到一个与编码有关的小问题时,我通常会采取一些萨满的行为.
直到这一刻我才将perl字符串视为字节序列,这对我的任务非常适合.现在我需要对UTF-8编码文件进行一些处理,这里就麻烦了.
首先,我将文件读入字符串,如下所示:
open(my $in,'<',$ARGV[0]) or die "cannot open file $ARGV[0] for reading"; binmode($in,':utf8'); my $contents; { local $/; $contents = <$in>; } close($in);
然后只需打印它:
print $contents;
我得到两件事:警告宽字符在< scriptname>线< n>和控制台中的垃圾.所以我可以得出结论,perl字符串有一个“字符”的概念,可以是“宽”的,但是当打印时,这些“宽”字符在控制台中表示为多个字节,而不是单个“字符”.
(我现在想知道为什么我以前使用二进制文件的所有经验都非常适合我预期它在没有任何“字符”问题的情况下工作的方式).
为什么然后我在控制台看到垃圾?如果perl在一些已知的编码中将字符串存储为字符,我认为找到控制台编码和正确打印文本并不是一个大问题. (我使用Windows,BTW).
如果perl将字符串存储为可变宽度字符序列(例如,使用相同的UTF-8编码),为什么这样做?从我的C经验来看,处理字符串是PAIN.
更新.
我使用两台计算机进行测试,一台运行安装了英语语言包的Windows 7 x64,但使用ActivePerl 5.10.1 x64进行俄语区域设置(因此我将cp866作为OEM代码页,cp1251作为ANSI);另一个运行Windows XP 32位俄语本地化与Cygwin Perl 5.10.0.
感谢链接,现在我对正在发生的事情以及应该如何完成工作有了更深刻的理解.
解决方法
在打印之前,您需要将字符编码回字节.
use Encode; utf8::encode($contents);
对于除unicode之外的其他编码,还有两种形式的编码. (那句话回声太多,不是吗?)
这是一个很好的参考. (可能会更多,但这是我的第一篇文章.)查看perlunitut,以及关于Joel on Software的unicode文章.
http://www.ahinea.com/en/tech/perl-unicode-struggle.html
哦,它必须使用多字节字符串,因为否则它不是unicode.