【Python】文本編碼與chardet模塊

簡介

以前一直對(duì)字符編碼很模糊悔据,感覺編碼方式有很多疏橄,在網(wǎng)上查資料也總是看的暈頭轉(zhuǎn)向伟叛,所以在這里先將幾種常見的編碼方式的關(guān)系總結(jié)一下。
常見的字符編碼——ASCII淤击、Unicode匠抗、GBKUTF-8

  • ASCII

ASCII編碼的全稱是American Standard Code for Information Interchange污抬,美國信息互換標(biāo)準(zhǔn)代碼汞贸。這是一種最早的、只用來保存英文文字的編碼方式印机。ASCII編碼方式只使用了1個(gè)字節(jié)(8比特位矢腻,可以組合出256種不同的狀態(tài))中0~127種組合存儲(chǔ)了英文的文字。

  • GBK

當(dāng)計(jì)算機(jī)普及到國內(nèi)時(shí)射赛,因?yàn)闈h字的常用字就有將近6000個(gè)多柑,使用ASCII編碼已經(jīng)完全不能滿足使用的需求了。
所以在1981年楣责,國家標(biāo)準(zhǔn)總局發(fā)布了GB2312(中國國家標(biāo)準(zhǔn)簡體中文字符集)顷蟆,使用2個(gè)字節(jié)的組合,當(dāng)兩個(gè)大于127的字符連在一起時(shí)腐魂,就表示一個(gè)漢字帐偎,這樣就組合出了7000多個(gè)簡體字。
后來因?yàn)闈h字的擴(kuò)展需求蛔屹,發(fā)布了GBK標(biāo)準(zhǔn)削樊,K是擴(kuò)展一次漢語拼音的聲母。即不再要求第二個(gè)字節(jié)大于127,只要第一個(gè)字節(jié)大于127漫贞,則表示這是一個(gè)漢字的開始甸箱。這樣共收錄了將近22000個(gè)漢字和符號(hào)。且兼容了GB2312標(biāo)準(zhǔn)迅脐。
2005年時(shí)修訂了GB18030標(biāo)準(zhǔn)芍殖,支持了國內(nèi)少數(shù)民族的文字,共收錄漢字70000余個(gè)谴蔑。兼容了GBK標(biāo)準(zhǔn)豌骏。

  • Unicode

就如國內(nèi)定義了GB2312標(biāo)準(zhǔn)一樣,當(dāng)時(shí)各個(gè)國家都規(guī)定了適用于自己語言的一套編碼方式隐锭。但是這就導(dǎo)致各國相互之間誰也不懂誰的編碼窃躲,裝錯(cuò)字符系統(tǒng)就會(huì)導(dǎo)致顯示全是亂碼。
所以這時(shí)ISO(International Standards Organization钦睡,國際標(biāo)準(zhǔn)化組織)推出了Unicode標(biāo)準(zhǔn)用以解決這個(gè)問題蒂窒。
Unicode標(biāo)識(shí)以2個(gè)字節(jié)長度的數(shù)字來標(biāo)識(shí)所有字符,除了英文以外的字符全部重新進(jìn)行了統(tǒng)一編碼荞怒。
注意Unicode只是一種標(biāo)準(zhǔn)洒琢,不是編碼方式,給予了每個(gè)字符一個(gè)16比特位的數(shù)字標(biāo)識(shí)褐桌,至于這個(gè)字符在內(nèi)存中是由幾個(gè)字節(jié)存儲(chǔ)纬凤,并不是Unicode標(biāo)準(zhǔn)規(guī)定的。

  • UTF-8

Unicode標(biāo)準(zhǔn)制定后撩嚼,在很長的一段時(shí)間內(nèi)無法推廣,直到互聯(lián)網(wǎng)的普及挖帘,強(qiáng)烈要求出現(xiàn)一種統(tǒng)一的編碼方式完丽。然后就誕生了UTF-8,這個(gè)使用Unicode標(biāo)準(zhǔn)的編碼方式拇舀。
注意:因此逻族,UTF-8是Unicode標(biāo)準(zhǔn)的一種實(shí)現(xiàn)方式

UTF-8的編碼規(guī)則很簡單骄崩,只有兩條:

  1. 對(duì)于單字節(jié)的符號(hào)聘鳞,字節(jié)的第一位設(shè)為0,后面7位為這個(gè)符號(hào)的 Unicode 碼要拂。因此對(duì)于英語字母抠璃,UTF-8 編碼和ASCII碼是相同的
  2. 對(duì)于n字節(jié)的符號(hào)(n > 1)脱惰,第一個(gè)字節(jié)的前n位都設(shè)為1搏嗡,第n + 1位設(shè)為0,后面字節(jié)的前兩位一律設(shè)為10。剩下的沒有提及的二進(jìn)制位采盒,全部為這個(gè)符號(hào)的 Unicode 碼旧乞。

下表為編碼規(guī)則,字母x表示可用編碼的位磅氨。

Unicode符號(hào)范圍 UTF-8編碼方式(二進(jìn)制)
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


以漢字嚴(yán)為例尺栖,演示如何實(shí)現(xiàn)UTF-8編碼:

嚴(yán)的Unicode碼是4E25100111000100101),根據(jù)上表烦租,可以發(fā)現(xiàn)4E25處在第三行的范圍內(nèi)(0000 0800 - 0000 FFFF)延赌,因此嚴(yán)的 UTF-8 編碼需要三個(gè)字節(jié),即格式是1110xxxx 10xxxxxx 10xxxxxx左权。然后皮胡,從嚴(yán)的最后一個(gè)二進(jìn)制位開始,依次從后向前填入格式中的x赏迟,多出的位補(bǔ)0屡贺。這樣就得到了,嚴(yán)的 UTF-8 編碼是11100100 10111000 10100101锌杀,轉(zhuǎn)換成十六進(jìn)制就是E4B8A5甩栈。

由此可見,漢字的Unicode碼和UTF-8編碼是不同的糕再,它們之間可以通過規(guī)則進(jìn)行轉(zhuǎn)換量没。

注意 : 漢字的Unicode碼是2個(gè)字節(jié),而UTF-8碼是3個(gè)字節(jié)


Python 中的編碼方式轉(zhuǎn)換

Python3中的字符序列類型有兩種:strbytes突想。

bytes對(duì)象是一串十六進(jìn)制格式字符序列殴蹄,如b'\xe6\x88\x91',前方的b標(biāo)示這串字符是bytes對(duì)象猾担。

將bytes對(duì)象通過上述的某種編碼方式可以解析為字符串袭灯,如將b'\xe6\x88\x91'使用UTF-8編碼方式解碼得到漢字,而使用GBK編碼方式解碼無法得到完整的漢字绑嘹。

Python3中使用encode()decode()進(jìn)行字符與二進(jìn)制序列之間的轉(zhuǎn)換稽荧,可以這樣理解:
encode(編碼)就是把人能看懂的漢字,轉(zhuǎn)換為機(jī)器能看懂的二進(jìn)制序列工腋。
decode(解碼)就是把人看不懂的二進(jìn)制序列姨丈,轉(zhuǎn)換為漢字。

使用encode()decode()時(shí)擅腰,有個(gè)encoding參數(shù)蟋恬,默認(rèn)值為UTF-8,指定了對(duì)字符串進(jìn)行編碼或解碼時(shí)趁冈,使用的編碼方式筋现。


有關(guān)文件的編碼方式

前面說了那么多,還沒有講到有關(guān)文件的編碼方式,而且可能平時(shí)使用open()打開文件read()的時(shí)候矾飞,并沒有指定編碼方式一膨,也能夠正常打印出來文件的內(nèi)容。

文件的編碼方式是在open()是指定的洒沦,有個(gè)encoding參數(shù)豹绪,作用和字符串解碼一樣,如果以非二進(jìn)制模式(b)打開文件申眼,會(huì)默認(rèn)通過UTF-8方式打開瞒津。

所以一份GBK編碼的文件,如果不以二進(jìn)制模式打開括尸、且不設(shè)置這個(gè)encoding參數(shù)巷蚪,是會(huì)報(bào)解碼錯(cuò)誤的(UnicodeDecodeError)。

當(dāng)然濒翻,如果以二進(jìn)制模式打開文件屁柏,再讀取到的文本就已經(jīng)是二進(jìn)制序列了,不涉及encode問題有送,而是該以什么解碼方式將二進(jìn)制序列轉(zhuǎn)換為人可以讀懂的漢字淌喻。

所以對(duì)于一個(gè)未知編碼方式的文件,如何通過代碼獲取其編碼方式雀摘,然后轉(zhuǎn)換為我們所期望的編碼方式呢裸删?
Python提供了一個(gè)第三方庫chardet,是char detect的縮寫阵赠,字符監(jiān)測(cè)涯塔。
將二進(jìn)制序列傳入chardet.detect()方法,然后會(huì)返回一個(gè)字典清蚀。該字典有3個(gè)鍵值匕荸。

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

encoding是所識(shí)別出來該二進(jìn)制序列的編碼方式。
confidence是所識(shí)別出來的encoding正確概率(1.0表示100%)轧铁。
language是該編碼方式適用的語言。
可以根據(jù)confidence概率決定是否使用encoding編碼方式旦棉。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末齿风,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子绑洛,更是在濱河造成了極大的恐慌救斑,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,039評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件真屯,死亡現(xiàn)場離奇詭異脸候,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門运沦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來泵额,“玉大人,你說我怎么就攤上這事携添〖廾ぃ” “怎么了?”我有些...
    開封第一講書人閱讀 165,417評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵烈掠,是天一觀的道長羞秤。 經(jīng)常有香客問我,道長左敌,這世上最難降的妖魔是什么瘾蛋? 我笑而不...
    開封第一講書人閱讀 58,868評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮矫限,結(jié)果婚禮上哺哼,老公的妹妹穿的比我還像新娘。我一直安慰自己奇唤,他們只是感情好幸斥,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,892評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著咬扇,像睡著了一般甲葬。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上懈贺,一...
    開封第一講書人閱讀 51,692評(píng)論 1 305
  • 那天经窖,我揣著相機(jī)與錄音,去河邊找鬼梭灿。 笑死画侣,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的堡妒。 我是一名探鬼主播配乱,決...
    沈念sama閱讀 40,416評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼皮迟!你這毒婦竟也來了搬泥?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,326評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤伏尼,失蹤者是張志新(化名)和其女友劉穎忿檩,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體爆阶,經(jīng)...
    沈念sama閱讀 45,782評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡燥透,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,957評(píng)論 3 337
  • 正文 我和宋清朗相戀三年沙咏,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片班套。...
    茶點(diǎn)故事閱讀 40,102評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡肢藐,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出孽尽,到底是詐尸還是另有隱情窖壕,我是刑警寧澤,帶...
    沈念sama閱讀 35,790評(píng)論 5 346
  • 正文 年R本政府宣布杉女,位于F島的核電站瞻讽,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏熏挎。R本人自食惡果不足惜速勇,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,442評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望坎拐。 院中可真熱鬧烦磁,春花似錦、人聲如沸哼勇。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽积担。三九已至陨晶,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間帝璧,已是汗流浹背先誉。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評(píng)論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留的烁,地道東北人褐耳。 一個(gè)月前我還...
    沈念sama閱讀 48,332評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像渴庆,于是被迫代替她去往敵國和親铃芦。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,044評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容