亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Python > 正文

python黑魔法之編碼轉換

2020-01-04 17:48:29
字體:
來源:轉載
供稿:網友
這篇文章主要介紹了python黑魔法之編碼轉換,分析了python編碼轉換的方法,感興趣的小伙伴們可以參考一下
 

我們在使用其他語言的庫做編碼轉換時,對于無法理解的字符,通常的處理也只有兩種(或三種):

  • 拋異常
  • 替換成替代字符
  • 跳過

但是在復雜的現實世界中,由于各種不靠譜,我們處理的文本總會出現那么些不和諧因素,比如混合編碼。在這種情況下,又回到了上面的處理辦法。

那么問題來了,python有沒有更好地辦法呢?

答案是,有!

python的編碼轉換流程實際上是兩段式轉換:

source -> unicode -> dest

首先將字符串從原始編碼轉換成unicode。再將unicode轉換成目標編碼。

第一步我們一般采用decode()或者 unicode() 這兩個函數完成。
第二步我們使用encode()函數完成。

在這里我們說的黑魔法就是在第一步實現。

decode和unicode函數都有一個叫做errors的可選參數??纯垂俜降拿枋觯?/p>

  • errors may be given to set a different error
  • handling scheme. Default is 'strict' meaning that encoding errors raise
  • a UnicodeDecodeError. Other possible values are 'ignore' and 'replace'
  • as well as any other name registered with codecs. register_error that is
  • able to handle UnicodeDecodeErrors.

這個參數通常有三種值:

  • strict 默認值。如果出現編碼錯誤,則會拋出UnicodeDecodeError。
  • ignore 跳過。
  • replace 用?替換。

好了,看到最后一句話了嗎?好戲上演了!

模塊codec有一個函數叫做register_error。他的作用讓用戶可以注冊自定義的errors處理方法。
用來處理UnicodeDecodeError。

我們看看函數原型:

codecs.register_error(name, error_handler)

name: 錯誤處理的名稱。用以填寫在decode函數的error參數中。
error_handler: 處理函數。該函數接受一個異常參數。
返回一個tuple,該tuple有2個元素,第一個是糾錯后的字符串,第二個是繼續decode的起始位置

有了上面的基本概念。我們看下具體實現:

def cjk_error(e):  if not isinstance(e, UnicodeDecodeError):    raise TypeError("don't know how to handle %r" % exc)   if exc.end + 1 > len(exc.object):     raise TypeError('unknown codec ,the object too short!')   ch1 = ord(exc.object[exc.start:exc.end])   newpos = exc.end + 1   ch2 = ord(exc.object[exc.start + 1:newpos])   sk = exc.object[exc.start:newpos]   if 0x81<=ch1<=0xFE and (0x40<=ch2<=0x7E or 0x7E<=ch2<=0xFE): # GBK     return (unicode(sk,'cp936'), newpos)   if 0x81<=ch1<=0xFE and (0x40<=ch2<=0x7E or 0xA1<=ch2<=0xFE): # BIG5     return (unicode(sk,'big5'), newpos)   raise TypeError('unknown codec !') codecs.register_error("cjk_replace", cjk_replace) 

上面這個是我從網上copy的。開始我覺得很不錯,但是后來發現是個很不經推敲的算法。
比如utf8和gbk在前兩個字節就有交集的部分。當一個utf8的字符串以gbk編碼decode的時候,出現錯誤是從第三個字節開始(前兩個字節也能夠在gbk編碼范圍中對應到一個漢字)。
如:

a = "你"              # utf8編碼:'/xe4/xbd/xa0'c = unicode(a[:2],'gbk')  # 正常返回c = unicode(a, 'gbk')    # UnicodeDecodeError 。錯誤發生在第三個字節

所以針對這種情況,做了下改進:

import codecdef cjk_replace(e):  if not isinstance(e, UnicodeDecodeError):    raise TypeError("invalid exception type %s" e)  src = e.encoding  if src in ('gbk','gb18030', 'big5'):    beg = e.start - 2    if beg >= 0:      try:        return unicode(e.object[beg:e.end], 'utf8'), e.end + 1      except:        pass  if exc.end + 1 > len(exc.object):    raise TypeError('unknown codec ,the object too short!')  ch1 = ord(exc.object[exc.start:exc.end])  newpos = exc.end + 1  ch2 = ord(exc.object[exc.start + 1:newpos])  sk = exc.object[exc.start:newpos]  if src != 'gbk' and 0x81<=ch1<=0xFE and (0x40<=ch2<=0x7E or 0x7E<=ch2<=0xFE): # GBK    return (unicode(sk,'cp936'), newpos)  if src != 'big5' and 0x81<=ch1<=0xFE and (0x40<=ch2<=0x7E or 0xA1<=ch2<=0xFE): # BIG5    return (unicode(sk,'big5'), newpos)  raise TypeError('unknown codec !')codecs.register_error("cjk_replace", cjk_replace)

當然,這個邏輯其實還是不夠嚴謹的。雖然對于這種混合編碼這種畸形活處理有點較真兒。
不過既然python提供這樣的能力,大家可以一起來討論下,我們怎么可以做的更好?


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美日韩国产丝袜美女| 草民午夜欧美限制a级福利片| 国产精品看片资源| 国产成人一区三区| 亚洲第一精品电影| 超碰精品一区二区三区乱码| 亚洲精品成人网| 色播久久人人爽人人爽人人片视av| 亚洲人成在线观看网站高清| 亚洲精品视频中文字幕| 亚洲欧美日韩直播| 欧美激情欧美激情| 伊人久久久久久久久久| 97精品欧美一区二区三区| 日韩精品在线观看一区二区| 亚洲网站视频福利| 国产欧美精品一区二区| 色偷偷888欧美精品久久久| 久久国产天堂福利天堂| 91国产美女在线观看| 日韩av在线一区| 亚洲女人被黑人巨大进入al| 亚洲人在线视频| 欧美国产欧美亚洲国产日韩mv天天看完整| 亚洲精品电影网在线观看| 久久久久久久久久久91| 欧美一区二区三区免费视| 色婷婷av一区二区三区在线观看| 亚洲伊人久久大香线蕉av| 国产美女久久精品香蕉69| 国产一区二区动漫| 亚洲一区二区三区视频播放| 久久久久久久影视| 精品少妇一区二区30p| 久久激情五月丁香伊人| 91国产中文字幕| 亚洲人线精品午夜| 久久精品美女视频网站| 日韩成人av网址| 色综合色综合网色综合| 亚洲高清一二三区| 综合欧美国产视频二区| 日韩国产中文字幕| 久久久91精品| 日本19禁啪啪免费观看www| 欧美国产乱视频| 最近更新的2019中文字幕| 国模精品视频一区二区| 日韩在线视频网| 91chinesevideo永久地址| 黄色成人在线免费| 在线电影欧美日韩一区二区私密| 国产精品吹潮在线观看| 久久久久久亚洲精品中文字幕| 欧美日韩一区二区三区在线免费观看| 国产精品久久久久久久久久ktv| 久久精品国产一区二区电影| 日韩免费av片在线观看| 狠狠躁夜夜躁人人躁婷婷91| 欧美激情视频在线免费观看 欧美视频免费一| 欧美成人免费观看| 69视频在线播放| 国产一区视频在线播放| 欧美一区二区三区图| 国产欧美精品日韩| 日韩电影大片中文字幕| 日韩中文在线不卡| 欧美精品电影在线| 久久久久久久久中文字幕| 久久久久九九九九| 亚洲缚视频在线观看| 国产精品成av人在线视午夜片| 亚洲国产精品va在线看黑人| 欧美大学生性色视频| 日韩在线中文字幕| 日韩欧美aⅴ综合网站发布| 国产精品网站入口| 91福利视频网| 欧美性视频在线| 日韩最新免费不卡| 国产有码在线一区二区视频| 亚洲一级黄色av| 欧美专区在线观看| 欧洲s码亚洲m码精品一区| 在线电影欧美日韩一区二区私密| 欧美日韩免费观看中文| 欧美最猛黑人xxxx黑人猛叫黄| 中文字幕一区二区精品| 国产美女久久精品香蕉69| 亚洲精品短视频| 日韩在线欧美在线国产在线| 57pao国产精品一区| 久久影院中文字幕| 97国产一区二区精品久久呦| 成人网在线免费看| 97在线免费视频| 欧美另类精品xxxx孕妇| 欧美一区二区大胆人体摄影专业网站| 成人国产精品久久久| 国产精品入口福利| 青青草原成人在线视频| 国产日韩在线看| 国产在线98福利播放视频| 91影院在线免费观看视频| 亚洲japanese制服美女| 日本国产一区二区三区| 亚洲视频在线播放| 亚洲精品成人av| 欧美激情18p| 国产精品久久久久9999| 国产一区二区三区视频免费| 国内精品久久久久久中文字幕| 国产91精品久久久| 国产视频精品免费播放| 91大神福利视频在线| 国产精品欧美在线| 欧美日韩亚洲国产一区| 国模精品一区二区三区色天香| 欧美午夜美女看片| 国产精品678| 91深夜福利视频| 55夜色66夜色国产精品视频| 国产精品热视频| 国产v综合v亚洲欧美久久| 国产精品视频久久久久| 欧美日韩一区二区在线| 亚洲国产婷婷香蕉久久久久久| 美女扒开尿口让男人操亚洲视频网站| 精品视频中文字幕| 国外视频精品毛片| 国产剧情久久久久久| 国产97人人超碰caoprom| 成人a在线视频| 欧美日韩人人澡狠狠躁视频| 免费91麻豆精品国产自产在线观看| 久久久久国色av免费观看性色| 国产自产女人91一区在线观看| 成人免费激情视频| 欧美亚洲国产日本| 欧美激情视频在线免费观看 欧美视频免费一| 国产精品流白浆视频| 亚洲国产精品va在看黑人| 欧美精品videos| 国产精品91免费在线| 81精品国产乱码久久久久久| 美女久久久久久久久久久| 亚洲视频在线播放| 亚洲激情视频网站| 亚洲福利在线视频| 国产午夜精品一区二区三区| 91精品视频网站| 97视频在线观看免费高清完整版在线观看| 久久艳片www.17c.com| 日韩一区视频在线| 久久久免费观看视频| 搡老女人一区二区三区视频tv| 亚洲精品视频网上网址在线观看| 秋霞av国产精品一区| 亚洲毛茸茸少妇高潮呻吟| 日韩av大片在线| 欧美国产日本在线| 高清一区二区三区日本久| 久久中国妇女中文字幕| 992tv成人免费视频|