Python字符集问题转载

对应中国人来说字符集的相互转换真是麻烦,搞不好就是大串的乱码,实在有必要多多复习一下基本概念!!
ISO8859-1,通常叫做Latin-1。Latin-1包括了书写所有西方欧洲语言不可缺少的附加字符。而gb2312是标准中文字符集。
UTF-8 是 UNICODE 的一种变长字符编码,即 RFC 3629。简单的说——大字符集。可以解决多种语言文本显示问题,从而实现应用国际化和本地化。
对系统来讲,UTF-8 编码可以通过屏蔽位和移位操作快速读写,排序更加容易。UTF-8 是字节顺序无关的,它的字节顺序在所有系统中都是一样的。因此 UTF-8 具有更高的性能。
在chinaunix看到篇实例讲解,很是直观,下面就贴出来,与大家共享!!
python 代码

  1. >>> a = "我"
  2. >>> b = unicode(a,"gb2312")
  3. >>> a.__class__
  4. <type 'str'>
  5. >>> b.__class__
  6. <type 'unicode'>
  7. >>>  

看出来了吧,两种字符串。
再来
python 代码

  1. >>> a
  2. '\xce\xd2'
  3. >>> b
  4. u'\u6211'  

变量a是两个字符,b是一个unicode字符。
关于这两种字符串,Python文档-->LanguageReference-->DataModel-->The standard type hierarchy-->
Sequences,有一些Strings,Unicode的描述。
至于
python 代码

  1. >>> z = u"我"
  2. >>> #这种代码,其实什么都不是。
  3. >>> z.__class__
  4. <type 'unicode'>
  5. >>> z
  6. u'\xce\xd2'  

看到了吧,这个奇怪的东西......
后来在WindowsXP、纯python命令行下试过,得出的结论不同,z的结果变成了u'\u6211',这里完全不应
该在pyshell下作试验的,看来还有很多问题尚未理解清楚

再来看看encode,decode
什么情况用encode,什么情况又是decode呢,刚开始总是被搞昏。其实各种本地字符集的英文名是
Coded Character Set,要转换为Coded,肯定是要encode了,同样,从里面解出来也应该叫decode……

decode就是把其他编码转换为unicode,等同于unicode函数;encode就是把unicode编码的字符串转换

特定编码。在pyshell里继续:
a是Str类型的,所以再用encode会报错。用print输出时会调用默认编码转换为系统编码?

python 代码

  1. >>> a.decode("gb2312")
  2. u'\u6211'
  3. >>> print a.decode("gb2312")
  4. 我
  5. >>> a.encode("gb2312")
  6. Traceback (most recent call last):
  7. File "<input>", line 1, in ?
  8. UnicodeDecodeError: 'ascii' codec can't decode byte 0xce in position 0: ordinal not in range(128)  

b是unicode类型,打印时需要先encode(编码)成系统编码
python 代码

  1. >>> print b.encode("gb2312")
  2. 我
  3. >>> b.encode("gb2312")
  4. '\xce\xd2'
  5. >>> b.decode("gb2312")
  6. Traceback (most recent call last):
  7. File "<input>", line 1, in ?
  8. UnicodeEncodeError: 'ascii' codec can't encode character u'\u6211' in position 0: ordinal not in
  range(128

字符串内码的转换,是开发中经常遇到的问题。
在Java中,我们可以先对某个String调用getByte(),由结果生成新String的办法来转码,也可以用NIO包里面的Charset来实现。
在Python中,可以对String调用decode和encode方法来实现转码。
比如,若要将某个String对象s从gbk内码转换为UTF-8,可以如下操作
s.decode(’gbk’).encode(’utf-8′)

可是,在实际开发中,我发现,这种办法经常会出现异常:
UnicodeDecodeError: ‘gbk’ codec can’t decode bytes in position 30664-30665: illegal multibyte sequence

这是因为遇到了非法字符——尤其是在某些用C/C++编写的程序中,全角空格往往有多种不同的实现方式,比如\xa3\xa0,或者\xa4\x57,这 些字符,看起来都是全角空格,但它们并不是“合法”的全角空格(真正的全角空格是\xa1\xa1),因此在转码的过程中出现了异常。

这样的问题很让人头疼,因为只要字符串中出现了一个非法字符,整个字符串——有时候,就是整篇文章——就都无法转码。

幸运的是,tiny找到了完美的解决办法(我因此被批评看文档不仔细,汗啊……)
s.decode(’gbk’, ‘ignore’).encode(’utf-8′)

因为decode的函数原型是decode([encoding], [errors='strict']),可以用第二个参数控制错误处理的策略,默认的参数就是strict,代表遇到非法字符时抛出异常;
如果设置为ignore,则会忽略非法字符;
如果设置为replace,则会用?取代非法字符;
如果设置为xmlcharrefreplace,则使用XML的字符引用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值