简介
相信很多程序员都碰到过字符串乱码的问题,有的人初步分析下就容易定位出问题来,而有的人就像无头苍蝇一样,就是瞎撞,gbk不好使,就换utf-8,再不行decode,encode…,一堆尝试。
其实,一开始,我也是一样,对字符集不是很懂,不管是使用c/c++编程,还是python,只要碰到程序里有中文了,就不知所措,花了几天时间研究了字符集相关知识,总算有点收获。大体列举如**意事项:
- 要处理的数据是什么字符集的
- 你的编译器默认使用什么字符集,是否和你要处理的数据的字符集一样呢
- 当你在控制台打印数据的时候,数据的字符集是否和控制台使用的字符集一致呢
所以,在处理数据的时候一不小心就会乱了,下面我用python进行相关演示。
关于字符集介绍,我有专门的文章进行介绍,建议先把字符集相关的知识了解透彻了,再进行相关编程工作。
python2.x
python2缺省使用ascii编码处理数据,所以程序中有中文时就需要注意了。
演示1:win7,系统字符集gbk,用notepad新建test.py文件(文件编码缺省也是gbk的),输入以下代码
s1='helloworld'
print s1
执行结果(正确显示):
E:\>python test.py
helloworld
演示2:win7,系统字符集gbk,用notepad新建test.py文件(文件编码缺省也是gbk的),输入以下代码
s1='你好'
print s1
执行结果(错误):
E:\>python test.py
File "test.py", line 1
SyntaxError: Non-ASCII character '\xc4' in file test.py on line 1, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details
上面的提示信息很明确了,说是在test.py文件中找到了非ascii字符’\xc4’,原因也提示了,说是没有进行编码声明,那python2编译器就使用默认ascii字符集进行解析,发现非ascii字符,报语法错误。
演示3:win7,系统字符集gbk,用notepad新建test.py文件(文件编码缺省也是gbk的),输入以下代码
#coding:gbk
s1='你好'
print s1
执行结果(正确显示):
E:\>python test.py
你好
这里的代码比上面演示2的代码多了一行(#coding:gbk),这一行的作用是声明文件的编码方式是gbk,那么python2解释器就安装gbk方式去解析test.py文件,解析正确,同时将s1输出到控制台正确显示。
演示4:win7,系统字符集gbk,用notepad++新建test.py文件(编码方式使用utf-8),输入以下代码
#coding:utf-8
s1='你好'
print s1
执行结果(乱码):
E:\>python test.py
浣犲ソ
这里的代码与上面演示3代码唯一的不同是gbk换成了utf-8,文件的编码方式由utf-8换成了gbk,有人可能会想utf-8不是通用码吗?怎么还会乱码,这里需要说下,utf-8不是通用码,它只是unicode字符集的一种编码方式,真正的通用码是unicode码。这里没有报语法错误,而是输出乱码,是因为我的控制台使用的是gbk编码,而当utf-8字节流(E4 BD A0 E5 A5 BD)输出到控制台时,反而按gbk字符集解析字符,变成了 浣犲ソ,明白了吧。控制台是无法帮你把Utf-8转换成gbk的。
演示5:win7,系统字符集gbk,用notepad新建test.py文件(文件编码缺省也是gbk的),输入以下代码
#coding:utf-8
s1='你好'
print s1
执行结果(正确显示,瞎猫碰上死耗子):
E:\>python test.py
你好
这种方式是最需要注意的,文件的真实编码是gbk的,而代码里却声明文件的编码是utf-8,欺骗了python2解释器,python2解释器就安装utf-8去解析源码文件,解析结果放到s1中,然后将s1的字节流(C4 E3 BA C3)输出到控制台,而控制台恰好使用的是gbk编码,和文件编码一样,所以就被正确显示出来了,好吧。
演示6:win7,系统字符集gbk,用notepad新建test.py文件(文件编码缺省也是gbk的),输入以下代码
#coding:gbk
s1=u'你好'
print s1
执行结果(正确显示):
E:\>python test.py
你好
解释下上面的代码:#coding:gbk声明test.py文件编码为gbk,然后python2解释器就以gbk编码解析文件test.py,当遇到u’你好’ 字符串时,就将其从gbk转换为unicode编码,然后赋值给s1变量,最后输出到控制台,因为unicode码是通用码,输出到控制台时,会隐式转换为gbk,然后正确显示。
演示7:win7,系统字符集gbk,用notepad++新建test.py文件(编码方式使用utf-8),输入以下代码
#coding:utf-8
s1=u'你好'
print s1
执行结果(正确显示):
E:\>python test.py
你好
解释下上面的代码:#coding:utf-8声明test.py文件编码为utf-8,然后python2解释器就以utf-8编码解析文件test.py,当遇到u’你好’ 字符串时,就将其从utf-8转换为unicode编码,然后赋值给s1变量,最后输出到控制台,因为unicode码是通用码,输出到控制台时,会隐式转换为gbk,然后正确显示。
python3.x
python3缺省使用utf-8处理数据,同时所有的字符串都是以unicode字符集编码。