簡體   English   中英

Python3:讀取utf8編碼的字節串

[英]Python3: reading utf8 encoded bytestrings

我的程序使用“ iwlist掃描”的輸出來生成報告。 它工作正常,除非網絡名稱(ESSID)包含非Ascii字符。
IEEE802.11規定ESSID可能包含UTF8字符。 但是,這些essid由iwlist報告為已編碼的字節串。 例:
ESSID: “F \\ XC3 \\ xAAte”
\\ xC3 \\ xAA實際上是“ê”的UTF-8編碼
我找不到一種方法來指定“打開”這些字節字符串應自動轉換為UTF-8字符。
問題:解決我問題的最pythonic方法是什么?

PS:作為測試用例,我將以下行放在文件中(例如xx):
ESSID: “F \\ XC3 \\ xAAte”
然后執行:
打開('xx','rb')。read()。decode('UTF-8')
我的結果是:
'ESSID: “F \\ XC3 \\ xAAte” \\ n'

這實際上是一個兩步過程:將\\xNN代碼轉換為等效的字節值,然后將這些字節從UTF-8轉換為Unicode字符。 Python提供了unicode_escape編解碼器以簡化過程。 不幸的是,你需要一個額外的步驟-它不會轉換\\xNN到字節,它把它們轉換成字符,你需要將這些轉換回相當於字節。

因此,您最終需要進行3步轉換。 編碼為latin1是將字符轉換為字節的黑客。 之所以可以使用它,是因為Unicode將Latin-1編碼用於其前256個代碼點,從而為您提供1:1映射。

with open(filename, 'rb') as f:
    essid_raw = f.read()
    essid = essid_raw.decode('unicode_escape').encode('latin1').decode('utf-8')


>>> essid_raw = b'ESSID:"f\xC3\xAAte"'
>>> essid = essid_raw.decode('unicode_escape').encode('latin1').decode('utf-8')
>>> print(essid)
ESSID:"fête"

據我了解您的問題:

看起來您的文件根本沒有Unicode字符,但是它具有轉義的字符串。 因此,實際上不是8個字符而是一個ê符號- \\xC3\\xAA 因此,與其使用.decode("utf-8")從Unicode解碼, .decode('unicode_escape')從Unicode轉義字符( .decode('unicode_escape')解碼。

為了嘗試這個,我制作了一個帶有字符串的文件:

ESSID:"f\\xC3\\xAAte"

然后此腳本將打印以下內容:

>>> open( 'file','rb').read().decode('UTF-8')
ESSID:"f\xC3\xAAte"

如果您改用unicode_escape,您將獲得

>>> open( 'file','rb').read().decode('unicode_escape')
ESSID:"fête"

我在對自己說。
找不到python解決方案,所以我開發了我的。
方法是刪除“ \\ x”並將2個十六進制字符轉換為一個字節。 對每個\\ x重復一次。

def adapt( tb):
  # this function converts the weird UTF8 escaping used by 'iwlist scan'
  # iwlist outputs "f\xC3\xAAte" instead of "fête"
  # caution : input is not sanitized 
  i = 0
  while True:
    # suppress \x and replace the following 2 characters by their hex value 
    i = tb.find( b'\\\x', i)
    if i < 0: break
    tb = tb[:i] + bytes( [int( tb[ i+2:i+4], 16)]) + tb[i+4:]
    i += 1     # skip the preceding sequence
  return tb

用法:

txt = adapt( open( 'xx','rb').read()).decode()
print( txt)
ESSID:"fête"  

這是一個丑陋的hack,但效果很好。 我很樂意想要一個更好的解決方案。
感謝您的回答。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM