作者:孟岩 来源:CSDN博客 酷勤网收集 2007-12-01
Ruby中进行UTF-8编码检测的方法是String#unpack方法,传入 "U*" 模板。这个模板的意思是把字符串当成一个UTF-8串,分别把每一个Unicode字符转换成对应的代码点并组合为数组。字符串本身确实是UTF-8,则能够转换成功,否则将抛出异常。根据这种行为,给String添加如下实例方法:
class String
def utf8?
unpack('U*') rescue return false
true
end
end
以上程序在大部分情况下确实正确。但是我发现GB2312编码中,下列汉字的GB2312编码能够通过上面方法的检测,而被误认为是UTF-8串:
位、前、支、校、写、元
可能还有一些。因此,上述方法不适宜用来对可能包含GB2312编码的中文字串进行UTF-8编码检测。
注意这不是Ruby的问题,而是不同编码模式导致的本质难题。
可以做以下实验:
1. 打开notepad,写入一个‘位’字,不回车,直接以ANSI编码保存(注意必须用ANSI编码保存)。
2. 再次打开这个文件,你会看到显示出来的不是“位”字,而是λ。
同样,“前、支、校、写、元” 等单字也存在类似现象。
可见字符串编码检测并不容易。不知有没有什么可靠的方法(除了用Iconv库直试转以外),望知者不吝赐教。
评论
cloudwu 发表于2007-01-05 00:49:51 IP: 218.72.15.*| 如果想区分一个完整的字符串是 GBK 还是 UTF8 其实蛮简单的。 虽然做不到 100% 有效,单也比上面的方法强许多。 UTF8 是兼容 ascii 的,所以 0~127 就和 ascii 完全一致了。 gbk 的第一字节是高位为 1 的,第 2 字节可能高位为 0 。这种情况一定是 gbk ,因为 UTF8 对 >127 的编码一定每个字节高位为 1 。 另外,对于中文,UTF8 一定编码成 3 字节。(似乎亚洲文字都是,UTF8 中双字节好象只用于西方字符集) 所以型如 110***** 10****** 的,我们一概看成 gbk/gb2312 编码。这就解决了“位”的问题。 汉字以及汉字标点(包括日文汉字等),在 UTF8 中一定被编码成:1110**** 10****** 10****** 连续汉字数量不是 3 的倍数的 gb2312 编码的汉字字符串一定不会被误认为 UTF8 。用了一些gbk 扩展字,或是插入了一些 ascii 符号的字符串也几乎不会被认为是 UTF8 。 一般说来,只要汉字稍微多几个,gbk 串被误认为 UTF8 的可能性极其低。(只需要默认不使用 UTF8 中双字节表示的字符)可能性低,这里还有另外一个原因。UTF8 中汉字编码的第一个字节是 1110**** ,这处于汉字的 gb2312 中二级汉字(不常用汉字,区码从 11011000 开始)的编码空间。一般是一些生僻字才会碰上。 |
#
qiangsheng 发表于2007-01-05 10:32:21 IP: 218.28.167.*
| 还有联字,当初很著名的微软NOTEPAD鄙视联通的帖子,大家都忘了吗? |
#
zdg 发表于2007-01-05 20:57:06 IP:
| 如何判断编码有些方法,小侯和我做了些探讨,以下是2篇相关文章: http://blog.csdn.net/zdg/archive/2005/01/29/272643.aspx http://blog.csdn.net/houjianxun/archive/2005/02/24/299593.aspx |
来自:http://blog.csdn.net/myan/archive/2007/01/04/1474112.aspx

