pythonutf8转gbk 判断一个字符能否用gbk和utf8编码

阅读本文之前,需要了解GBK与UTF-8的编码知识,相关内容可以参考。

字符集错误转换导致的问题

UTF-8格式编码的字节流,按GBK字符集转换为字符串,会出现乱码,这很正常。但将其重新转为字节流,再用UTF-8字符集转为字符串,还是乱码。这就让我产生了疑惑,虽然使用错误的字符集必然导致乱码,但字节的信息并没有改变,因此再转为字节流,用正确的字符集解码,应该得到正常的字符串。但事实是,被错误字符集转换过的字符串,无法恢复到原来的字符集。

造成该问题的根源是字节发生了变化。GBK或UTF-8遇到无法解析的字符时,会使用特殊的字符代替,因此造成原有字节信息的丢失,无法恢复。

对于一串UTF-8编码的字节流,使用GBK进行解码。连续两个大于127的字节被认为是一个GBK编码的字符;若只读到一个大于127的字节,便发生错误,无法解析。此时,用字符'?'代替错误字节,ASCII码是63。
“樊”字为例,UTF-8编码使用三个字节表示该字符,字节码为[001010]([e6, a8, 8a])。使用GBK解码时,读到第一个字节大于127,则取两个字节解析为一个GBK字符。前两个字节e6 8a被解析为GBK字符——妯。 第三个字节无法解析,所以赋值为?,最后的结果是 妯?
可以看出,最后一个字节的信息丢失了,由8a变成3F,即使把结果再转换为字节流,也无法用utf-8字符集正确解析了。

对于一串GBK编码的字节流,使用UTF-8解码。UTF-8对于字节的格式有严格要求,当解析某个字符失败时,使用'?'(UTF-8编码为EF BF BD)代替。
继续以“樊”字为例,其GBK字节码为[101110]([B7, AE])。使用UTF-8解码时,根据规则,要求10开头的字节之前,必须有字节标识一个字符的长度,所以两个字节都无法解析。最后的字符串是??。
可以看出,所有的字节信息都丢失了,因此无法再使用GBK解析该字符串。
注意,UTF-8用?替换,是以字符为单位的。例如[000001]使用UTF-8解码,得到的结果是?A,而不是??A。根据第一个字节的格式,UTF-8期望将三个字节转换为一个字符。但最后一个字节不符合要求,所以前两个字节被一个?代替。而不是每个字节都被?代替。

原发布在个人博客,欢迎访问!!

}

平时用的最多的就是print输出看下效果,but 打印的时候老是能遇到知种编码报错这个字符不能编码那个字符不能解码等。

下面就做个测试记录下看哪种情况下会报错

cmd运行环境编码为936也就是gbk

先简单说下编码,unicode是国际统计的一种编码规范,utf-8就是使用这种规范实现的一种多字节编码。这个要搞清楚不清楚的自行搜索了解

源代码中给变量赋值字符串时默认是unicode也就是str类型这两个是同一个意思(这一点跟python2区别很大)

但是实际使用过程中却遇到很多报错

测试utf-8文本文件

在D盘根目录创建一个文本文件编码为utf-8里面写几个汉字

以二进制读取后解码并打印

如上面代码,我们把它转换成gbk编码编码的时候忽略错误试一下

这次cmd和pycharm下面都正常显示啦

}

即可获得3次抽奖机会,100%中奖。

可选中1个或多个下面的关键词,搜索相关资料。也可直接点“搜索资料”搜索整个问题。

}

我要回帖

更多关于 pythonutf8转gbk 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信