人工智能-機器人聊天語庫搭建

編碼/解碼問題是個大坑缰儿,其中的復雜性频祝,大多來自歷史包袱

由于計算機領域的分層架構和多平臺問題沧踏,這個問題被進一步加劇尤泽,unicode的出現(xiàn)欣簇,給這個問題帶來了曙光.

可是生活不總是那么美好的,有些時候坯约,一不小心熊咽,我們還是會掉到滿是泥沼的坑里

周末在鳳凰書城看一本數(shù)據(jù)清洗相關的書,其中說道噪聲數(shù)據(jù)的問題闹丐,有問題的編碼是噪聲的來源之一横殴,書中分享了不少好用的方法,在便簽里記了一些卿拴,加上之前筆記里的衫仑,正好整理成一篇文章

編碼問題

這里引《中文編碼雜談》中關于亂碼的討論

在Linux平臺上如果使用cat等命令查看文件中的中文內容時梨与,可能出現(xiàn)亂碼。這也是編碼的問題惑畴。簡單的說是文件時按照A編碼保存蛋欣,但是cat命令按照當前Locale設定的B編碼去查看航徙,在B和A不兼容的時候就出現(xiàn)了亂碼如贷。

核心概念

十分鐘搞清字符集和字符編碼

字符集

簡單的說字符集就規(guī)定了某個文字對應的二進制數(shù)字存放方式(編碼)和某串二進制數(shù)值代表了哪個文字(解碼)的轉換關系

字符編碼

字符編碼(英語:Character encoding)、字集碼是把字符集中的字符編碼為指定集合中某一對象(例如:比特模式到踏、自然數(shù)序列杠袱、8位組或者電脈沖),以便文本在計算機中存儲和通過通信網絡的傳遞窝稿。常見的例子包括將拉丁字母表編碼成摩斯電碼和ASCII楣富。其中,ASCII將字母伴榔、數(shù)字和其它符號編號纹蝴,并用7比特的二進制來表示這個整數(shù) --wikipedia

Unicode和UTF-8

Unicode對世界上大部分的文字系統(tǒng)進行了整理、編碼踪少,使得電腦可以用更為簡單的方式來呈現(xiàn)和處理文字塘安。

Unicode只是一個符號集,它只規(guī)定了符號的二進制代碼援奢,卻沒有規(guī)定這個二進制代碼應該如何存儲

而UTF-8就是字符編碼兼犯,是Unicode規(guī)則字庫的一種實現(xiàn)形式

Python中的編碼問題

Python編碼和Unicode一文中描述了python中可能出現(xiàn)的一些編解碼難題

原因之一是Python 2.x默認將所有的字符串當做ASCII來對待(python3中會好很多)

當你使用string類型時,實際上會儲存一個字節(jié)串

解碼字節(jié)流

你可以把字節(jié)流解碼(decode)成一個Unicode對象集漾,把一個Unicode 對象編碼(encode)為字節(jié)流

你最好是盡早的將字節(jié)流解碼為Unicode(字節(jié)流進入程序的時候)

你不能簡單地輸出一個Unicode對象切黔。它必須在輸出前被變成一個字節(jié)串

str/unicode

在mac下python2.7.5

# unicodeunicode_a=u"你好"type(unicode_a)# unicode_a# u'\u4f60\u597d'unicode_b=u'\u4f60\u597d'unicode_b# u'\u4f60\u597d'unicode_a==unicode_b# True# unicode_c = unicode("你好") python2會報錯,python會把所有東西作為字節(jié)流理解u'hello'==unicode("hello")#? True具篇,如果unicode_a.encode("utf-8")# '\xe4\xbd\xa0\xe5\xa5\xbd'################# strstr_a="你好"str_a# '\xe4\xbd\xa0\xe5\xa5\xbd'str_a.decode("utf-8")# u'\u4f60\u597d'str_a.decode("utf-8")==u"你好"# True

__repr__的目標是準確性纬霞,__str__的目標是可讀性

codecs模塊

codecs模塊能在處理字節(jié)流的時候提供很大幫助。你可以用定義的編碼來打開文件并且你從文件里讀取的內容會被自動轉化為Unicode對象驱显。

讀寫文件

當從一個文件讀取數(shù)據(jù)的時候险领,codecs.open 會創(chuàng)建一個文件對象能夠自動將utf-8編碼文件轉化為一個Unicode對象,而寫入文件這樣寫:

importcodecsfh=codecs.open("/tmp/utf-8.txt","w","utf-8")fh.write(u"\u2013")fh.close()

使用urllib流

stream=urllib.urlopen("http://www.google.com")Reader=codecs.getreader("utf-8")fh=Reader(stream)type(fh.read(1))# ,應該盡可能讓程序內部的數(shù)據(jù)都是

你必須對codecs模塊十分小心。你傳進去的東西必須是一個Unicode對象,否則它會自動將字節(jié)流作為ASCII進行解碼秒紧。

策略

python編解碼涉及的問題可能很多绢陌,上至大神下至小白,都可能受擾熔恢,為了保持簡單脐湾,我們可以保持這樣一種習慣:關注輸入輸出,內部保持unicode叙淌。

每當有數(shù)據(jù)進入程序秤掌,將其解碼(decode)為unicode(utf-8)

當有數(shù)據(jù)從程序中輸出時愁铺,將其編碼(encode)為utf-8

最佳實踐:

最先解碼(解碼為unicode對象),最后編碼(輸出為字節(jié)碼)

最先解碼意味著無論何時有字節(jié)流輸入闻鉴,需要盡早將輸入解碼為Unicode

最后編碼意味著只有你打算將文本輸出到某個地方時茵乱,才把它編碼為字節(jié)流。這個輸出可能是一個文件孟岛,一個數(shù)據(jù)庫瓶竭,一個socket等等

默認使用utf-8編碼

使用codecs和Unicode對象來簡化處理

codecs模塊能夠讓我們在處理諸如文件或socket這樣的流的時候能少踩一些坑。如果沒有codecs提供的這個工具渠羞,你就必須將文件內容讀取為字節(jié)流斤贰,然后將這個字節(jié)流解碼為Unicode對象。

codecs模塊能夠讓你快速的將字節(jié)流轉化為Unicode對象次询,省去很多麻煩荧恍。

linux下的一些工具

file

file命令用來探測給定文件的類型,

參數(shù):

-i:顯示MIME類別。

-c:詳細顯示指令執(zhí)行過程屯吊,便于排錯或分析程序執(zhí)行的情形送巡;

file *

iconv

conv命令是用來轉換文件的編碼方式的,比如它可以將UTF8編碼的轉換成GB18030的編碼

iconv -f encoding -t encoding inputfile

iconv -f UTF-8 -t GBK file1 -o file2 //將一個UTF-8 編碼的文件轉換成GBK編碼

chardet

有時候我們不知道文件/字節(jié)流采用了什么編碼盒卸,可以讓chardet來猜測編碼骗爆,chardet是python的一個庫

傳輸編碼語法(transfer encoding syntax)

用于處理上一層次的字符編碼方案提供的字節(jié)序列。一般其功能包括兩種:一是把字節(jié)序列的值映射到一套更受限制的值域內世落,以滿足傳輸環(huán)境的限制淮腾,例如Email傳輸時Base64或者quoted-printable,都是把8位的字節(jié)編碼為7位長的數(shù)據(jù)屉佳;另一是壓縮字節(jié)序列的值谷朝,如LZW或者進程長度編碼等無損壓縮技術。

BASE64編碼

Base64常用于在通常處理文本數(shù)據(jù)的場合武花,表示圆凰、傳輸、存儲一些二進制數(shù)據(jù)

常用于在URL体箕、Cookie专钉、網頁中傳輸少量二進制數(shù)據(jù)。

所謂Base64累铅,就是說選出64個字符----小寫字母a-z跃须、大寫字母A-Z、數(shù)字0-9娃兽、符號"+"菇民、"/"(再加上作為墊字的"=",實際上是65個字符)----作為一個基本字符集。然后第练,其他所有符號都轉換成這個字符集中的字符阔馋。

關于base64更多的細節(jié)可以參考維基百科和Base64筆記

在python中實現(xiàn)

importbase64base64.b64encode('hello')#aGVsbG8=? , 被編碼的不是應該是二進制數(shù)據(jù)吧娇掏,python的二進制默認被解析為ascii呕寝?,在這里hello無論是b'hello'還是'hello'/u'hello'婴梧,結果都一樣base64.b64decode("aGVsbG8=")# helloa=u'你好'# \u4f60\u597db=base64.b64encode(a.encode("utf-8"))#5L2g5aW9c=base64.b64decode(b)# \xe4\xbd\xa0\xe5\xa5\xbdc.decode("utf-8")# u'\u4f60\u597d'# 由于標準的Base64編碼后可能出現(xiàn)字符+和/下梢,在URL中就不能直接作為參數(shù),所以又有一種"url safe"的base64編碼志秃,其實就是把字符+和/分別變成-和_d=u"哈里謝頓".encode("utf-8")# \xe5\x93\x88\xe9\x87\x8c\xe8\xb0\xa2\xe9\xa1\xbfbase64.b64encode(d)# 5ZOI6YeM6LCi6aG/ , 有反斜杠e=base64.urlsafe_b64encode(d)# 5ZOI6YeM6LCi6aG_base64.urlsafe_b64decode(e)# \xe5\x93\x88\xe9\x87\x8c\xe8\xb0\xa2\xe9\xa1\xbf

url中的編碼問題

一般而言使用urllib庫中的urlencode函數(shù)就好了

fromurllibimporturlencodedata={'name':'小明',#u'小明'則需要encode為字節(jié)碼'age':'10歲'}printurlencode(data)# age=10%E5%B2%81&name=%E5%B0%8F%E6%98%8E#僅對字符串進行轉碼可以使用quotefromurllibimportquotequote('小明')#%E5%B0%8F%E6%98%8E'

如果有大量此類工作可以考慮使用furl

在線工具

在線編碼轉換

UrlEncode編碼/UrlDecode解碼

Unicode編碼轉換:還包括unix時間戳

一些細碎知識

Windows簡體中文版中怔球,ANSI是默認的編碼方式嚼酝。對于英文文件是ASCII編碼浮还,對于簡體中文文件是GB2312編碼(繁體中文版會采用Big5碼)

python中字節(jié)流和unicode的代碼視角比較

stackoverflow Python unicode equal comparison failed

參考

字符編碼

十分鐘搞清字符集和字符編碼

10分鐘學會理解和解決MySQL亂碼問題

字符編碼筆記:ASCII,Unicode和UTF-8

Python編碼和Unicode

Python: 熟悉又陌生的字符編碼

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末闽巩,一起剝皮案震驚了整個濱河市钧舌,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌涎跨,老刑警劉巖洼冻,帶你破解...
    沈念sama閱讀 206,723評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異隅很,居然都是意外死亡撞牢,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評論 2 382
  • 文/潘曉璐 我一進店門叔营,熙熙樓的掌柜王于貴愁眉苦臉地迎上來屋彪,“玉大人,你說我怎么就攤上這事绒尊⌒蠡樱” “怎么了?”我有些...
    開封第一講書人閱讀 152,998評論 0 344
  • 文/不壞的土叔 我叫張陵婴谱,是天一觀的道長蟹但。 經常有香客問我,道長谭羔,這世上最難降的妖魔是什么华糖? 我笑而不...
    開封第一講書人閱讀 55,323評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮瘟裸,結果婚禮上客叉,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好十办,可當我...
    茶點故事閱讀 64,355評論 5 374
  • 文/花漫 我一把揭開白布秀撇。 她就那樣靜靜地躺著,像睡著了一般向族。 火紅的嫁衣襯著肌膚如雪呵燕。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,079評論 1 285
  • 那天件相,我揣著相機與錄音再扭,去河邊找鬼。 笑死夜矗,一個胖子當著我的面吹牛泛范,可吹牛的內容都是我干的。 我是一名探鬼主播紊撕,決...
    沈念sama閱讀 38,389評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼罢荡,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了对扶?” 一聲冷哼從身側響起区赵,我...
    開封第一講書人閱讀 37,019評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎浪南,沒想到半個月后笼才,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 43,519評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡络凿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,971評論 2 325
  • 正文 我和宋清朗相戀三年骡送,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片絮记。...
    茶點故事閱讀 38,100評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡摔踱,死狀恐怖,靈堂內的尸體忽然破棺而出到千,到底是詐尸還是另有隱情昌渤,我是刑警寧澤,帶...
    沈念sama閱讀 33,738評論 4 324
  • 正文 年R本政府宣布憔四,位于F島的核電站膀息,受9級特大地震影響,放射性物質發(fā)生泄漏了赵。R本人自食惡果不足惜潜支,卻給世界環(huán)境...
    茶點故事閱讀 39,293評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望柿汛。 院中可真熱鬧冗酿,春花似錦埠对、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至弱判,卻和暖如春襟沮,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背昌腰。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評論 1 262
  • 我被黑心中介騙來泰國打工开伏, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人遭商。 一個月前我還...
    沈念sama閱讀 45,547評論 2 354
  • 正文 我出身青樓固灵,卻偏偏與公主長得像,于是被迫代替她去往敵國和親劫流。 傳聞我的和親對象是個殘疾皇子巫玻,可洞房花燭夜當晚...
    茶點故事閱讀 42,834評論 2 345

推薦閱讀更多精彩內容