我使用iconv库将使用UTF-8的现代输入源与使用Latin1(即CP1252(ISO-8859-1的超集))的旧系统进行接口(interface)。
该接口(interface)最近未能转换法语字符串“Éducation”,其中的“É”编码为hex 45 CC 81
。请注意,目标编码确实有一个“É”字符,编码为C9
。
为什么iconv转换“É”失败?我检查了MacOS X 10.7.3附带的iconv命令行工具说它不能转换,并且PERL iconv模块也失败了。
令人困惑的是,“É”字符(编码为C3 89
)的组合形式可以很好地转换。
这是iconv的错误,还是我错过了什么?
请注意,如果我尝试从UTF-16转换(“É”被编码为由00 C9
组成或分解的00 45 03 01
)转换,我也会遇到同样的问题。
最佳答案
不幸的是,除了Mac OS X上安装的版本之外,iconv确实不处理UTF-8中的分解字符。
处理Mac文件名时,可以将iconv与“ utf8-mac ”字符集选项一起使用。它还考虑了一些idiosyncrasies of the Mac decomposed form。
但是,iconv或libiconv的非mac版本不支持此功能,并且我找不到Mac上提供此支持的源。
我同意您的观点,iconv应该能够处理UTF8的NFC和NFD形式,但是直到有人修补了源代码之后,我们才必须手动检测此问题并进行处理,然后再将其传递给iconv。
面对这个烦人的问题,我使用了Jukka建议的Perl的Unicode::Normalize模块。
#!/usr/bin/perl
use Encode qw/decode_utf8 encode_utf8/;
use Unicode::Normalize;
while (<>) {
print encode_utf8( NFC(decode_utf8 $_) );
}
关于unicode - 为什么iconv可以转换 "É"的分解形式而不是分解形式(从UTF-8到CP1252),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9892897/