python關於字元編碼問題的例項分析

2022-09-23 21:03:27 字數 2284 閱讀 7013

任何資料在計算機看來都是二進位制01組成的**,所以,為了能將資料儲存,就必須轉換成二進位制的資料,這其中的規則便是編碼。

本文所述均為字元編碼,那麼……就從字元編碼的發展講起吧。在字元編碼內首先出現的便是ascii碼了,它儲存了128個基本字元,僅需要1byte的資料,基本對應鍵盤上的大部分字元。很明顯,我們在其中找不到我們想要的中文字元,當然,中文也不是128個所能容納的,那麼我們就需要有其他的字元編碼。所以就中文而言有了』gb2312』這樣的編碼,同樣地,其他國家也有自己的字元編碼。這樣問題就來了,因為編碼規則不同,所以乙個碼可能對應多個字元,通過不同編碼方式解碼出來的文字完全不一樣,這樣的話就會出現我們常說的亂碼問題,而且,同一文章也無法相容兩種文字。為了統一這一標準unicode應運而生。unicode是在ascii編碼的基礎上進行了擴充套件,對ascii相容,也即,ascii碼的字元的unicode碼是在其基礎上加1byte的0,(這1byte的0便是』』(空字元)啦,所以ascii解碼時候完全不影響噠),unicode採用2byte資料儲存,完美解決了各國標準不一的問題。但是另乙個問題就產生了,就是上面所說的,ascii碼對應的字元是要兩倍的資料,造成了資源的極大浪費(畢竟英語還是使用最廣泛的語言啊),因此便有了我們現在最常用的utf-8編碼。utf-8編碼採用1-3byte資料儲存字元,ascii對應那些字元依然只需要1byte,中文等字元採用2-3byte的編碼,使資源得到了極大的節約。因此我們在檔案中在的字元採用utf-8編碼以節省空間,但當我們讀取他們的時候,就會重新編碼為unicode碼存到記憶體中,當我們儲存它的時候又會編碼為utf-8碼存到硬碟上。

編碼(encode)和解碼(decode)的問題困擾了我很久,但把之前學的基礎知識梳理一遍後就有了新的發現。首先,任何字串都一定有乙個編碼規則,不然這個字串是不會被計算機所認識的,我們在python中的字元是以unicode編碼儲存的,也就是說任何儲存在python的字元都是以unicode碼形式儲存的,每個字元都對應乙個unicode碼,就比如說』\u6587』是完全等價於』文』的:

>>> '\u6587'#後面四位是四個十六進製制數,剛好是unicode碼對應的2byte(乙個16進製制數相當於4個2進製數,也即4bit,2byte需要4個16進製制數)

'文'而且,我們也可以用chr(),ord()函式將字元進行與unicode碼的互相轉換:

>>> chr(25991)#十進位制的25991對應十六進製制數就是6587

'文'當然,python也只是用unicode碼儲存str,我們的str還是str,並不是乙個bytes,想要將它變成乙個bytes就需要呼叫encode方法:

>>> '文'.encode('utf-8')

b'\xe6\x96\x87' #bytes型別,編碼之後對應的位元組流,』\x』是轉義為16進製制數,每個1byte,一共3byteencode方法是將乙個str按照編碼方式轉化成bytes,這個bytes是我們所看不懂的,但卻是檔案傳輸時候所需要的,當我們想要把它再變回str時候是一定要按原來編碼方式進行decode,不然就會亂碼甚至引發無法解碼的錯誤:

b'\xe6\x96\x87'.decode('gb2312')

traceback (most recent call last):

file "", line 1, in

b'\xe6\x96\x87'.decode('gb2312')

unicodedecodeerror: 'gb2312' codec can't decode byte 0xe6 in position 0: illegal multibyte sequence

>>> b'\xe6\x96\x87'.decode('utf8')#這裡不區分utf8 utf-8的(大小寫也都行)

'文'在spider實戰過程中遇到了不少編碼問題,剛開始還經常將decode和encode弄混,下面記錄下遇到的編碼問題:

1.bs4庫:把修改bs4物件encoding屬性當做之後會對其進行encode,後來才明白原來只是申明編碼方式,事實上還是將html頁面(bytes)進行decode,這樣才得到我們所能看到的頁面,如果申明的編碼方式錯誤便會出現亂碼甚至無法decode的情況。

2.emoji的處理問題:當時是直接複製過來的,後來才明白是將無法解碼的bytes過濾,這樣就不會報錯了。

non_bmp_map = dict.fromkeys(range(0x10000, sys.maxunicode + 1), 0xfffd)

r.text.translate(non_bmp_map)#r.text是待解析的str1.解析頁面時候遇到「不間斷空白符 」無法解碼的問題:將html中獲得的str中的該字元進行替換

s.string.replace(u'\xa0',u' ')#s.string是待替換文字

關於字元編碼的問題

寫程式的人基本上都會遇到亂碼的問題,之前自己對字符集 編碼等問題也是一知半解,大概明白什麼意思,但卻說不清楚。由於公司需要做多語言,於是研究了一下,終於把字符集和編碼等問題弄明白了。ascii gb2312 gbk unicode utf 8 utf 16 ucs2 ucs4.對於很多人來說這些東西...

關於字元編碼的問題

這幾天一直在改 前輩 流下來的乙個程式,其中讓我很無語的是 他的字元編碼居然全在servlet 中進行轉碼的,就是這樣 string submit new string request.getparameter submit1 getbytes iso 8859 1 gbk 居然寫成這樣了 讓我來擴...

關於字元編碼的問題

在乙個activity裡面有乙個文字輸入框,我在後台通過 edittext et username edittext findviewbyid r.id.username string username new string et username.gettext tostring 這樣拿到的字串不...