Python的中文处理及其它

前段时间猛禽在写他的第一个Python程序,期间一直向我抱怨说Python的中文处理有这样那样的问题。说句实话我之前并没有花过很大的精力在这种编码处理方面,不过我很纳闷,难道Python的编码处理能力真这么弱么?于是去做了一些试验,现在来简单的聊几句。

我们知道在Unicode出现之前,处理中文是一件非常麻烦的事情。因为没有自己的独立编码,GB(GB2312、GBK、GB18030)码是用2个多个ASCII字符来表示的,这就带来了和ASCII码的区分、字数统计等等一系列的问题。而在Unicode中,中文、英文以及其它很多字符都有自己独立的编码,这样一来,就没有上述问题了。因此,在可能的环境中,使用Unicode处理中文,是最好的选择。


一般来说,对中文处理的主要流程可以如下:

原始字符串用相应的编码转为Unicode
中间处理一律采用Unicode
将Unicode转成需要的编码输出
在Python中,跟Unicode相关的元素有以下几个:u前缀、unicode函数、codecs。他们有什么联系和区别么?

u前缀表示后面跟的那个字符串常量是一个Unicode字符串。但它仅仅表示这是一个Unicode字符串,对字符串本身的编码却没有做任何改变。比如:

s = u"测试"
s的值是:

u'\xb2\xe2\xca\xd4'


s = "测试"
s的值是:

'\xb2\xe2\xca\xd4'
可以看到,除了前面的u前缀外,字符内部编码没有丝毫差别。因此,我们要得到一个Unicode的中文字符串,u前缀并不是一个好方法。那么u前缀有什么作用呢?我的猜想是对非英语字符可能能起作用,未经证实,猜错不管。

和u前缀不同,unicode函数有一个转换编码的过程,在转换过程中,用到了codecs。

s = unicode("测试", "gb2312")
s的值是:

u'\u6d4b\u8bd5'
可以看到,这时的s,是一个真正的双字节Unicode编码字符串了。

结合上面的中文处理流程,我们可以得到一个比较一般的Python中文处理的流程:

将欲处理的字符串用unicode函数,以正确的编码转换为Unicode
在程序中统一用Unicode字符串进行操作
输出时,使用encode方法,将Unicode再转换为所需的编码。
下面是一个简单的演示,用re库查询一个中文字符串并打印:


>>> p = re.compile(unicode("测试(.*)", "gb2312"))
>>> s = unicode("测试一二三", "gb2312")
>>> for i in p.findall(s):

print i.encode("gb2312")
一二三


说明一下:
所谓“正确的”编码,指得是指定编码和字符串本身的编码必须一致。这个其实并不那么容易判断,一般来说,我们直接输入的简体中文字符,有两种可能的编码:GB2312(GBK、GB18030)、以及UTF-8。
encode成本地编码的时候,必须要保证目标编码中存在欲转换字符的内码。encode这种操作一般是通过一个本地编码对应Unicode的编码转换表来进行的,事实上每个本地编码只能映射到Unicode的一部分。但是映射的区域是不同的,比如Big-5对应的Unicode的编码范围和GBK对应的就不一样(实际上这两个编码有部分范围是重叠的)。所以,Unicode的一些字符(比如本身就是从GB2312转换来的那些),可以映射到GBK,但未必可以映射到Big-5,如果你想转换到Big-5,很有可能就会出现编码找不到的异常。但UTF-8的码表范围实际上和Unicode是一样的(只是编码形式不同而已),所以,理论上来说,任何本地编码的字符,都可以被转换到UTF-8。
PS1: GB2312、GBK、GB18030本质上是同一种编码标准。只是在前者的基础上扩充了字符数量。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值