我们通常见到的字符串编码主要是三种GB2312/GBK、Unicode、UTF-8。GB2312/GBK是多字节(multibytes)编码的一种,属于“ASCII的加强版”,与之平行的由Big5、ShiftJIS之类的编码各自为政,所有这些用两个字节表示汉字的多字节编码标准统称为ANSI编码,同样的汉字在不同的ASNI编码中的表示是不同的。为了避免这个问题,Unicode应运而生,将全世界所有的字符统一编码到一个定长的结构中。Unicode解决了统一编码的问题,但带来了新的问题。第一点,Unicode和ASCII不兼容了,这是因为ASCII只有一个字节,而这一个字节肯定装不下Unicode。第二点,用Unicode传输开销变大了,这是因为很多文档二十六个字母(1个字节)就能解决了,用Unicode多了很多冗余的字节。因此UTF-8应运而生。UTF-8对Unicode进行变长编码(我们可以想象下Huffman树),通常长度在1-4字节。目前Linux系统使用的是UTF-8编码,而Windows内部则是UTF-16LE/GBK编码。

Python2的字符串表示

Python2中有表示字符串有str和Unicode两种。其中一个str字面量由""表示,我们也可以用''或者"""这类括号括起,一个Unicode字面量由u""括起。1

2

3

4

5

6

7

8"你好"

'xc4xe3xbaxc3'

u"你好"

u'u4f60u597d'

type("你好")

type(u"你好")

其中Unicode得益于ucs2/ucs4标准,在不同系统上都是固定的表示的。其中ucs2即Unicode16,比较常见,用2个字节(65536)来索引,一般表示是u"uxxxx",ucs4即Unicode32,一般表示是u"Uxxxxyyyy"在一些Python中也能见到。我们可以通过下面的代码来检测Python是哪一个1

2

3

4

5

6

7

8

9--enable-unicode=ucs4

>>> import sys

>>> print sys.maxunicode

1114111

--enable-unicode=ucs2

>>> import sys

>>> print sys.maxunicode

65535

str的表示取决于所在的系统,例如Linux是默认UTF8,上面的“你好”就会变为'/xe4/xbd/xa0/xe5/xa5/xbd',我们这里看到UTF8确实是一种字符的表示。1

2

3

4

5

6

7

8

9

10

11>>> "hello".encode("utf-8")

'hello'

>>> "hello".decode("gbk").encode("utf-8")

'hello'

>>> "你好".encode("utf-8")

Traceback (most recent call last):

File "", line 1, in

UnicodeDecodeError: 'ascii' codec can't decode byte 0xc4 in position 0: ordinal not in range(128)

>>> "你好".decode("gbk").encode("utf-8")

'xe4xbdxa0xe5xa5xbd'

Python2中字符串问题实录

reload

在Python2中出现编码问题时,很多人喜欢使用下面的语句来改变系统的默认编码1

2

3import sys

(sys)

sys.setdefaultencoding('utf-8')

这种策略通常用来解决下面这样的错误提示

UnicodeEncodeError: 'ascii' codec can't encode byte

现在ASCII码不能encode是吧,那我默认都用utf-8来encode总行了吧?但这样可能存在问题,博文中就举出了一个实例。对于多字节字符串str,我们之前默认用ASCII解码,要是解不开,就RE了。现在我们默认用utf-8解,utf-8阈值广,基本都能解开,不RE了,可是就不WA了么?样例中举出一个例子,一个latin-1编码的字符串,用utf-8解码不会报错,但解出来的结果并不对。因此在多字节编码规则不统一这个客观问题存在的情况下,不存在银弹。我们需要的是用chardet.detect来猜测编码。当猜测不出时我们只能不停地try,直到找到一个解码不报错的编码,虽然可能解出来还是乱码,因为可能一段byte串同时用utf-8、gbk、Big5等都能解码而不报错。

这里提供一个工具类,能够尽可能地猜测字节串所使用的编码1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23def ultimate_decode(doc):

def try_decode(s, try_decoding):

try:

res = s.decode(try_decoding)

return True, res

except UnicodeDecodeError:

return False, ""

if isinstance(doc, str):

predicted = chardet.detect(doc)

print predicted

if predicted['encoding'] and predicted['confidence'] > 0.5:

doc = doc.decode(predicted['encoding'])

else:

encodeing_list = ["utf-8", "gbk", "Big5", "EUC-JP"]

for e in encodeing_list:

state, res = try_decode(doc, e)

if state:

doc = res

break

if not isinstance(doc, unicode):

return None

return doc

coding

当我们在Python代码文件中需要加入中文时,我们需要在文件开头加上这两行中的一行,不然即使用上前面的reload大法都不行。1

2#-*- coding:utf-8 -*-

#coding: utf8

这是用来指定Python代码文件所使用的编码方式。在Python2.1时,这个机制还没有引入,我们只能通过unicode-escape的方式输入。一个类似的做法是很多json库dump的结果中常出现u打头的unicode-escape字符串,这是非常正常的现象。这样json库可以省事地避免编码问题,因为这样json文件现在都是ASCII码了。

伪装成Unicode的多字节

有时候我们会看到这种东西u'xe3x80x8axe5',首先这外面套了个u,应该是Unicode,但是里面却是x打头的multi-bytes的形式,这往往是由于错误调用unicode()函数所致的。对此,python提供了raw_unicode_escape来解决这个问题

正则匹配

由于存在特殊符号的原因,使用正则匹配时宜使用Unicode而不是多字节匹配。但是以下的编码在Win10和某些Linux发行版上都跑不了,但在MacOS和Ubuntu上能够正常运行,去StackOverflow问了,他们认为这是一个Bug,所以暂时还是先用上面的方法。

python2编码_Python2字符编码相关推荐

  1. Python2和python3字符编码的区别

    Python2和python3字符编码的区别 一.字符编码应用值Python 1. 执行Python程序的三个阶段 Python test.py(执行test.py的第一步,一定是先将文件内容从硬盘读 ...

  2. php %3cphp用大括号表示,整理HTML5中支持的URL编码与字符编码_html5教程技巧

    URL 编码URL 编码就是将 URLs 中不宜打印的字符或者具有特殊意义的字符转换为 Web 浏览器和服务器明白且普遍接受的表示法. 这些字符包括: ASCII 控制字符 - 不宜打印的字符通常用于 ...

  3. python 查看字符编码,[Python]判断系统编码和字符编码chardet

    这里使用了字符编码判断的一个模块chardet 使用esay_install 直接安装就可以了 os环境win7  ide:wingide 1 使用默认环境编码 ''' 查看系统编码 ''' impo ...

  4. mysql特殊编码_Mysql 字符编码

    知识补充:数据库字符编码 一.MySQL支持的字符集 1.查看所有可用的字符集 show character set; 或者查看information_schema.character_sets,也可 ...

  5. ansi编码_Java 字符编码

    点击上方蓝字关注我们! 作者介绍 王云静,Java 开发工程师,2018 年 7 月加入去哪儿网,目前在目的地 - 呼叫中心.曾获得过 ACM 亚洲区域赛铜牌. ----- 基本概念 字符集 字符(C ...

  6. 解决文件内容的中文乱码_字符集_字符编码_字符编码方案

    从第三方下载的java源文件,打开查看里面的中文全部是乱码,无论你使用什么字符编码集都无法正常显示,该文件是用UTF-8编码存档的,使用UTF-8解码也同样是乱码,相信很多人遇到类似的问题,我这里解决 ...

  7. 【转】刨根究底字符编码之三——字符编码的由来

    字符编码的由来 一.为什么需要对字符进行编码 1. 计算机一开始发明出来时是用来解决数字计算问题的,后来人们发现,计算机还可以做更多的事,例如文本处理. 但计算机其实挺"笨"的,它 ...

  8. unix系统编码 java_JAVA字符编码系列三:Java应用中的编码问题

    这两天抽时间又总结/整理了一下各种编码的实际编码方式,和在Java应用中的使用情况,在这里记录下来以便日后参考. 为了构成一个完整的对文字编码的认识和深入把握,以便处理在Java开发过程中遇到的各种问 ...

  9. java json设置编码_java-JSON字符编码

    java-JSON字符编码 我的Java Web应用程序提交了一个AJAX请求,该请求返回JSON,例如: {'value': 'aériennes'} 当网页上显示"aériennes&q ...

最新文章

  1. centos7上搭建http服务器以及设置目录访问
  2. 在js中获取input中的value
  3. SAP B1在添加物料主数据时,出现错误提示‘xxxx代码已存在’的解决方法
  4. 不同步节点在线使用Remix开发以太坊Dapp及solidity学习入门 ( 一 ):智能合约HelloWorld
  5. Google 警告开发者:所有 Android App 需要三天的审核时间!
  6. 手机上有没有学python的软件-三款可以在安卓手机上运行Python代码的软件
  7. asppython份额_为什么JAVA份额那么高,存在感却不如Python?
  8. 最长上升子序列问题(O(n^2)算法)
  9. Leetcode: Reorder List Summary: Reverse a LinkedList
  10. smarty手册阅读笔记——变量调节器
  11. STM8S103之tim2PWM输出
  12. word段落居中的快捷键_在word中文字居中的快捷键?
  13. 了解计算机软件系统教学设计,认识计算机》教学设计
  14. 今日头条的排名算法_今日头条旗下悟空问答的排名算法规则
  15. 联想Filez zBox2022企业版为企业的 “零信任体系”构建保驾护航
  16. worldwind 三维模型加载优化总结
  17. 【bzoj1050】[HAOI2006]旅行comf
  18. 应对Apple Music断续费后歌单被删除的一个解决方案
  19. 提醒:两性养生有别 男靠吃女靠睡
  20. 拼多多搜索智能推广使用教程及FAQ

热门文章

  1. Docker 安装 redis 、Redis docker 方式部署
  2. 破解 IntelliJ IDEA 、免费注册方法、注册码
  3. 2019南昌网络赛  I. Yukino With Subinterval 树状数组套线段树
  4. NOIP2018划水记
  5. opencv:图像的基本变换
  6. 框架模式和设计模式的区别
  7. 探讨C#中字符串的加密
  8. 刷脸考勤,重新定位校园管理
  9. JavaScript服务器端开发技术(对象属性的枚举与查询)
  10. 使用Jmeter对mysql进行性能测试入门