上一篇:[Perl]引用传递和值传递 - 下一篇:[Perl]标量环境和列表环境总结
版权声明:可以任意转载,但转载时必须标明原作者charlee、原始链接http://tech.idv2.com/2008/10/28/perl-utf8-c3c2-problem/以及本声明。
在处理多语言编码、使用UTF-8时,偶尔会遇到这个我称之为“c3c2问题”的问题。花了一天时间好不容易找到了原因所在,写在这里希望对遇到的人有所帮助。基于Perl语言写的,可能是Perl的专有问题,不过其他的语言若遇到类似的现象也可作为参考。
现象
进行编码转换时出现乱码。转换后的结果类似于下面的样子:
c3 a3 c2 81 c2 82 ...
看起来就像是正确的字符序列中加入了许多\xc3、\xc2的字符。
原因
对非utf-8字符序列进行 utf8::encode 或者 Encode::from_to($str, 'utf8', '...') 等,就会出现 c3 a3 c2 81... 一样的字符。 也就是说,把不是utf8编码的东西当作utf8编码来使用,就出现这个现象。
例如下面的例子。
#!/usr/bin/perl use Encode; $str1 = "あああ"; utf8::decode($str1); $str1 .= "あああ"; utf8::encode($str1); print $str1; print "----"; $str2 = "あああ"; Encode::from_to($str2, "UTF-8", "Shift_JIS"); utf8::encode($str2); print $str2;
执行结果如下:
$ perl mojibake.pl | xxd 0000000: e381 82e3 8182 e381 82c3 a3c2 81c2 82c3 ................ 0000010: a3c2 81c2 82c3 a3c2 81c2 822d 2d2d 2dc2 ...........----. 0000020: 82c2 a0c2 82c2 a0c2 82c2 a0 ...........
这里$str1是utf8字符流和字节流的混合体(实际上这是不对的),$str2是将shift-jis的字节流进行encode。其结果都会产生大量的\xc3和\xc2。
可能的原因:
- 将decode过的字符串和未decode的字符串连接在一起使用
- 对字符串连续进行两次 utf8 -> 其他编码的转换
