【Python】文本编码与chardet模块

简介

以前一直对字符编码很模糊,感觉编码方式有很多,在网上查资料也总是看的晕头转向,所以在这里先将几种常见的编码方式的关系总结一下。
常见的字符编码——ASCIIUnicodeGBKUTF-8

  • ASCII

ASCII编码的全称是American Standard Code for Information Interchange,美国信息互换标准代码。这是一种最早的、只用来保存英文文字的编码方式。ASCII编码方式只使用了1个字节(8比特位,可以组合出256种不同的状态)中0~127种组合存储了英文的文字。

  • GBK

当计算机普及到国内时,因为汉字的常用字就有将近6000个,使用ASCII编码已经完全不能满足使用的需求了。
所以在1981年,国家标准总局发布了GB2312(中国国家标准简体中文字符集),使用2个字节的组合,当两个大于127的字符连在一起时,就表示一个汉字,这样就组合出了7000多个简体字。
后来因为汉字的扩展需求,发布了GBK标准,K是扩展一次汉语拼音的声母。即不再要求第二个字节大于127,只要第一个字节大于127,则表示这是一个汉字的开始。这样共收录了将近22000个汉字和符号。且兼容了GB2312标准。
2005年时修订了GB18030标准,支持了国内少数民族的文字,共收录汉字70000余个。兼容了GBK标准。

  • Unicode

就如国内定义了GB2312标准一样,当时各个国家都规定了适用于自己语言的一套编码方式。但是这就导致各国相互之间谁也不懂谁的编码,装错字符系统就会导致显示全是乱码。
所以这时ISO(International Standards Organization,国际标准化组织)推出了Unicode标准用以解决这个问题。
Unicode标识以2个字节长度的数字来标识所有字符,除了英文以外的字符全部重新进行了统一编码。
注意Unicode只是一种标准,不是编码方式,给予了每个字符一个16比特位的数字标识,至于这个字符在内存中是由几个字节存储,并不是Unicode标准规定的。

  • UTF-8

Unicode标准制定后,在很长的一段时间内无法推广,直到互联网的普及,强烈要求出现一种统一的编码方式。然后就诞生了UTF-8,这个使用Unicode标准的编码方式。
注意:因此,UTF-8是Unicode标准的一种实现方式

UTF-8的编码规则很简单,只有两条:

  1. 对于单字节的符号,字节的第一位设为0,后面7位为这个符号的 Unicode 码。因此对于英语字母,UTF-8 编码和ASCII码是相同的
  2. 对于n字节的符号(n > 1),第一个字节的前n位都设为1,第n + 1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的 Unicode 码。

下表为编码规则,字母x表示可用编码的位。

Unicode符号范围 UTF-8编码方式(二进制)
0000 0000-0000 007F 0xxxxxxx
0000 0080-0000 07FF 110xxxxx 10xxxxxx
0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
0001 0000-0010 FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx


以汉字为例,演示如何实现UTF-8编码:

的Unicode码是4E25100111000100101),根据上表,可以发现4E25处在第三行的范围内(0000 0800 - 0000 FFFF),因此的 UTF-8 编码需要三个字节,即格式是1110xxxx 10xxxxxx 10xxxxxx。然后,从的最后一个二进制位开始,依次从后向前填入格式中的x,多出的位补0。这样就得到了,的 UTF-8 编码是11100100 10111000 10100101,转换成十六进制就是E4B8A5

由此可见,汉字的Unicode码和UTF-8编码是不同的,它们之间可以通过规则进行转换

注意 : 汉字的Unicode码是2个字节,而UTF-8码是3个字节


Python 中的编码方式转换

Python3中的字符序列类型有两种:strbytes

bytes对象是一串十六进制格式字符序列,如b'\xe6\x88\x91',前方的b标示这串字符是bytes对象。

将bytes对象通过上述的某种编码方式可以解析为字符串,如将b'\xe6\x88\x91'使用UTF-8编码方式解码得到汉字,而使用GBK编码方式解码无法得到完整的汉字。

Python3中使用encode()decode()进行字符与二进制序列之间的转换,可以这样理解:
encode(编码)就是把人能看懂的汉字,转换为机器能看懂的二进制序列。
decode(解码)就是把人看不懂的二进制序列,转换为汉字。

使用encode()decode()时,有个encoding参数,默认值为UTF-8,指定了对字符串进行编码或解码时,使用的编码方式。


有关文件的编码方式

前面说了那么多,还没有讲到有关文件的编码方式,而且可能平时使用open()打开文件read()的时候,并没有指定编码方式,也能够正常打印出来文件的内容。

文件的编码方式是在open()是指定的,有个encoding参数,作用和字符串解码一样,如果以非二进制模式(b)打开文件,会默认通过UTF-8方式打开。

所以一份GBK编码的文件,如果不以二进制模式打开、且不设置这个encoding参数,是会报解码错误的(UnicodeDecodeError)。

当然,如果以二进制模式打开文件,再读取到的文本就已经是二进制序列了,不涉及encode问题,而是该以什么解码方式将二进制序列转换为人可以读懂的汉字。

所以对于一个未知编码方式的文件,如何通过代码获取其编码方式,然后转换为我们所期望的编码方式呢?
Python提供了一个第三方库chardet,是char detect的缩写,字符监测。
将二进制序列传入chardet.detect()方法,然后会返回一个字典。该字典有3个键值。

{
    'encoding': 'GB2312',
    'confidence': 0.99,
    'language': 'Chinese'
}

encoding是所识别出来该二进制序列的编码方式。
confidence是所识别出来的encoding正确概率(1.0表示100%)。
language是该编码方式适用的语言。
可以根据confidence概率决定是否使用encoding编码方式。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343

推荐阅读更多精彩内容