小结Python的中文处理 [
来源:互联网 发布:重庆房地产楼盘数据库 编辑:程序博客网 时间:2024/04/29 07:40
- Python的中文处理
- 一、使用中文字符
- 在python源码中如果使用了中文字符,运行时会有错误,解决的办法是在源码的开头部分加入字符编码的声明,下面是一个例子:
- #!/usr/bin/env python
- # -*- coding: cp936 -*-
- Python Tutorial中指出,python的源文件可以编码ASCII以外的字符集,最好的做法是在#!行后面用一个特殊的注释行来定义字符集:
- # -*- coding: encoding -*-
- 根据这个声明,Python会尝试将文件中的字符编码转为encoding编码,并且,它尽可能的将指定地编码直接写成Unicode文本。
- 注意,coding:encoding只是告诉Python文件使用了encoding格式的编码,但是编辑器可能会以自己的方式存储.py文件,因此最后文件保存的时候还需要编码中选指定的ecoding才行。
- 二、中文字符的存储
- >>> str = u"中文"
- >>> str
- u'\xd6\xd0\xce\xc4'
- >>> str = "中文"
- >>> str
- '\xd6\xd0\xce\xc4'
- u"中文"只是声明unicode,实际的编码并没有变。这样子就发生变化了:
- >>> str = "中文"
- >>> str
- '\xd6\xd0\xce\xc4'
- >>> str = str.decode("gb2312")
- >>> str
- u'\u4e2d\u6587'
- 更进一步:
- >>> s = '中文'
- >>> s.decode('gb2312')
- u'\u4e2d\u6587'
- >>> len(s)
- 4
- >>> len(s.decode('gb2312'))
- 2
- >>> s = u'中文'
- >>> len(s)
- 4
- >>> s = '中文test'
- >>> len(s)
- 8
- >>> len(s.decode('gb2312'))
- 6
- >>> s = '中文test,'
- >>> len(s)
- 10
- >>> len(s.decode('gb2312'))
- 7
- 可以看出,对于实际Non-ASCII编码存储的字符串,python可以正确的识别出其中的中文字符以及中文上下文中的标点符号。
- 前缀“u”表示“后面这个字符串“是一个Unicode字符串”,这仅仅是一个声明,并不表示这个字符串就真的是Unicode了;就好比某正太声称自己已满18岁,但实际上他的真实年龄并不确定,现在体育界年龄造假可不稀罕幺!
- 那么声明成u有什么作用呢?对于Python来说,只要你声明某字符串是Unicode,它就会用Unicode的一套机制对它进行处理。比方说,做字符串操作的时候会动用到内部的Unicode处理函数,保存的时候以Unicode字符(双字节)进行保存。等等。显而易见,对于一个实际上并不是Unicode的字符串,做Unicode动作的处理,是有可能会出问题的。u前缀只适用于你的字符串常量真的是Unicode的情况。
- 三、中文字符的IO操作
- 用python处理字符串很容易,但是在处理中文的时候需要注意一些问题。比如:
- a = "我们是python爱好者"
- print a[0]
- 只能输出“我”字的前半部分,要想输出整个的“我”字还需要:
- b = a[0:2]
- print b
- 才行,很不方便,并且当一段文本中同时有中英文如何处理?最好的办法就是转换为unicode。像这样:
- c = unicode(a, "gb2312")
- print c[0]
- 这个时候c的下标对应的就是每一个字符,不再是字节,并且通过len(c)就可以获得字符数!还可以很方便的转换为其他编码,比如转换为utf-8:
- d = c.encode("utf-8")
- 四、<type ‘str’>和<type ‘unicode’>
- <type ‘str’>将字符串看作是字节的序列,而<type ‘unicode’>则将其看作是字符的序列,单个字符可能占用多个字节;字节相对于字符,其在存储层次中更低一些。
- str转换为unicode要decode,可以这样想,因为要把字节序列解释成字符序列,字节序列是底层的存放方式,解码(decode)成更高层的字符以便使用;同理,unicode转换为str要encode,就象信息编码(encode)后才存储一样:
- s.decode(encoding) <type 'str'> to <type 'unicode'>
- u.encode(encoding) <type 'unicode'> to <type 'str'>
- 例如:
- >>> s = 'str'
- >>> type(s)
- <type 'str'>
- >>> type(s.decode())
- <type 'unicode'>
- >>> s = u'str'
- >>> type(s)
- <type 'unicode'>
- >>> type(s.encode())
- <type 'str'>
- 处理中文数据时最好采用如下方式:
- 1. Decode early(尽早decode, 将文件中的内容转化成unicode再进行下一步处理)
- 2. Unicode everywhere (程序内部处理都用unicode)
- 3. Encode late (最后encode回所需的encoding, 例如把最终结果写进结果文件)
- 下面是一个简单的演示,用re库查询一个中文字符串并打印:
- >>> p = re.compile(unicode("测试(.*)", "gb2312"))
- >>> s = unicode("测试一二三", "gb2312")
- >>> for i in p.findall(s):
- print i.encode("gb2312")
- 一二三
- 五、跨平台处理技巧
- 如果一个project必须在两个平台上开发,程序应该使用同样的encoding,比如要求所有的文件都使用UTF-8,如果实在不能统一(一般是为了满足许多所谓专家学者莫名其妙的要求),可以退而求其次,用当前系统编码决定文件内的编码:
- import locale
- import string
- import re
- #根据当前系统的encoding构造需要的编码取值
- lang = string.upper(locale.setlocale(locale.LC_ALL, ""))
- textencoding = None
- #检查编码的值是不是满足我们需要的情况
- if re.match("UTF-8", lang) != None:
- # UTF-8编码
- textencoding = "utf-8"
- elif re.match(r"CHINESE|CP936", lang):
- # Windows下的GB编码
- textencoding = "gb18030"
- elif re.match(r"GB2312|GBK|GB18030", lang):
- # Linux下的GB编码
- textencoding = "gb18030"
- else:
- # 其他情况,抛个错误吧
- raise UnicodeError
- fd = file(filename, "r")
- fulltextlist = fd.readlines()
- # 把每一行转换成unicode
- for each in len(fulltextlist):
- fulltextlist[i] = unicode(each, textencoding)
- fd.close()
- # 如果要打印的话,可以用text.encode(encoding)来恢复成多字节编码
- 小结
- 一个比较一般的Python中文处理的流程:
- * 将欲处理的字符串用unicode函数以正确的编码转换为Unicode
- * 在程序中统一用Unicode字符串进行操作
- * 输出时,使用encode方法,将Unicode再转换为所需的编码
- 有几点要说明一下:
- * 所谓“正确的”编码,指得是指定编码和字符串本身的编码必须一致。这个其实并不那么容易判断,一般来说,我们直接输入的简体中文字符,有两种可能的编码: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
- * GB2312、GBK、GB18030本质上是同一种编码标准。只是在前者的基础上扩充了字符数量
- * UTF-8和GB编码不兼容
- 参考资料
- 1、[url]http://bbs3.chinaunix.net/thread-1389703-1-2.html[/url]
- 2、Python的中文处理及其它
- [url]http://www.go4pro.org/?p=38[/url]
- 3、Python处理中文的时候的一些小技巧
- [url]http://cocre.com/?p=461[/url]
- 4、Unicode In Python, Completely Demystified. Kumar McMillan
- [url]http://farmdev.com/talks/unicode[/url]
- 5、python中文处理好方法
- [url]http://www.okpython.com/bbs/viewthread.php?tid=311[/url]
- 6、Python的中文处理
- [url]http://hi.baidu.com/mrsz/blog/item/7812a5018c2cf2031d9583d2.html[/url]
0 0
- 小结Python的中文处理 [
- Python:中文处理小结
- Python的中文处理
- Python的中文处理
- Python的中文处理
- Python的中文处理
- Python的中文处理
- python中文件对象的操作小结
- python中文字符串的处理
- Python的中文编码处理
- [python]编码处理小结
- JNI中文处理问题小结
- JNI中文处理问题小结
- JNI中文处理问题小结
- linux中文乱码处理小结
- Servlet中文乱码处理小结
- iOS中文件下载监控及处理的小结
- Unicode和Python的中文处理
- 4个线程例子,2个线程对同一数字加法运算另外2个线程对同一共享数字减法运算
- android执行远程地址,就会报android.os.Net..... 这个原因是网络操作不能在主线程进行
- mac下修改hosts
- mac os x 编译hadoop
- Cocos2dx 线程同步
- 小结Python的中文处理 [
- 汇编优化工具
- ssh-copy-id
- WINxp Openvpn搭建
- Codeforces Round #250 Div1D 438D The Child and Sequence 线段树+势能分析
- 用第三方预编译包从源码在windows下搭建PCL(Point Cloud Library)开发环境
- 产品发布前的几个环境
- Python 字符串操作方法大全
- About Swift