之前使用python解碼二進(jìn)制字節(jié)流,遇到各種各樣的bug,現(xiàn)在對(duì)各種問(wèn)題進(jìn)行總結(jié)記錄
一. 解碼報(bào)錯(cuò):'utf-8' codec can't decode byte
1.bug再現(xiàn)
已知字節(jié)流生成時(shí)采用utf8編碼,但是解碼時(shí)莫名出現(xiàn)亂碼,如下:
text = b'\x00\x00\t\x00\x00\x002\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00[\x00\x00\x00n\x00\x00\x00p\x0b\xe2\x01\x00\x00\x00\x00 [9\x0b`\x7f\x00\x00'
text = text.decode()
print("text:", text)
---------------------------------------------------------------------------
UnicodeDecodeError Traceback (most recent call last)
<ipython-input-115-e6b2c457ec24> in <module>()
1 text = b'\x00\x00\t\x00\x00\x002\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00[\x00\x00\x00n\x00\x00\x00p\x0b\xe2\x01\x00\x00\x00\x00 [9\x0b`\x7f\x00\x00'
----> 2 text = text.decode()
3 print("text:", text)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe2 in position 36: invalid continuation byte
2. str.decode()語(yǔ)法
decode()方法語(yǔ)法:
str.decode(encoding='UTF-8',errors='strict')
參數(shù):
encoding -- 要使用的編碼,默認(rèn)"UTF-8",其余還有"gbk","unicode_escape","ascii","base64"等
errors -- 設(shè)置不同錯(cuò)誤的處理方案。默認(rèn)為 'strict',意為編碼錯(cuò)誤引起一個(gè)UnicodeError。
其余還有 'ignore', 'replace', 'xmlcharrefreplace', 'backslashreplace' 以及通過(guò) codecs.register_error() 注冊(cè)的任何值。
下面代碼采用不同的errors來(lái)encode帶有特殊字符的字符串,有興趣的同學(xué)可以嘗試下,感受區(qū)別
txt = "My name is St?le"
# print(txt.encode(encoding="ascii",errors="backslashreplace"))
# print(txt.encode(encoding="ascii",errors="ignore"))
# print(txt.encode(encoding="ascii",errors="namereplace"))
# print(txt.encode(encoding="ascii",errors="replace"))
# print(txt.encode(encoding="ascii",errors="xmlcharrefreplace"))
print(txt.encode(encoding="ascii",errors="strict"))
3. 解決解碼報(bào)錯(cuò)的bug
了解了這些,上面的bug表面上就很好解決了,直接設(shè)置errors的方式就可以了
text = b'\x00\x00\t\x00\x00\x002\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00[\x00\x00\x00n\x00\x00\x00p\x0b\xe2\x01\x00\x00\x00\x00 [9\x0b`\x7f\x00\x00'
text = text.decode("utf8", "ignore")
print("text:", text)
二、去除解碼后的空白占位符
python中去除空白字符的方式有很多種,各種方式似乎沒(méi)有太大差別,今天做了各種嘗試,做一個(gè)記錄
先看一下去除前的效果
text = b'2020-06-02 13:49:13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x86\x00\x00\x00\x00\x00\x00\x00\xf0\xa9'
text = text.decode("utf8", "ignore")
print(len(text), text, sep=">>>", end=">>>")
---------------------------------------------------------------------------
47>>>2020-06-02 13:49:13>>>
1.strip
text = b'2020-06-02 13:49:13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x86\x00\x00\x00\x00\x00\x00\x00\xf0\xa9'
text = text.decode("utf8", "ignore").strip("\x00")
print(len(text), text, sep=">>>", end=">>>")
---------------------------------------------------------------------------
19>>>2020-06-02 13:49:13>>>
2. replace
text = b'2020-06-02 13:49:13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x86\x00\x00\x00\x00\x00\x00\x00\xf0\xa9'
text = text.decode("utf8", "ignore").replace("\x00", "")
print(len(text), text, sep=">>>", end=">>>")
---------------------------------------------------------------------------
19>>>2020-06-02 13:49:13>>>
3. split
text = b'2020-06-02 13:49:13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x86\x00\x00\x00\x00\x00\x00\x00\xf0\xa9'
text = ''.join(text.decode("utf8", "ignore").split("\x00"))
print(len(text), text, sep=">>>", end=">>>")
---------------------------------------------------------------------------
19>>>2020-06-02 13:49:13>>>
編碼正常的情況下,上述三個(gè)方法看起來(lái)都沒(méi)什么問(wèn)題,都能達(dá)到想要的結(jié)果,權(quán)且先記錄下來(lái)
參考資料:
菜鳥(niǎo)教程:python decode()方法
w3school:python字符串encode()方法
Python encode()和decode()方法:字符串編碼轉(zhuǎn)換
python 字符串去空格