簡體   English   中英

Python加載'utf-16'文件無法解碼'\\ u0153'

[英]Python loading 'utf-16' file can't decode '\u0153'

我有一個編碼為utf-16的文本文件,它會引發以下字符的異常: '\œ'

UnicodeEncodeError:'charmap'編解碼器無法對字符'\\ u0153'進行編碼

我正在使用一個非常簡單的腳本來加載文件,我也嘗試忽略錯誤而無濟於事。 我究竟做錯了什么?

with open(filename, "r", encoding="utf-16", errors='replace') as data_file:    
    print(data_file.read())

這是文件的一部分,它打破了:

["Xinhua","Ürümqi"]

編輯:不知道為什么我的問題被誤解了。 希望這是更好的形成。

我該如何用Python閱讀這個文件?

示例文件鏈接 (UTF-16-LE文件)包含:

["Xinhua","Ürümqi"]

為什么這段代碼不起作用?

with open(filename, "r", encoding="utf-16", errors='replace') as data_file:    
    print(data_file.read())

最初困擾你的例外是因為你在終端模擬器中運行Python(或者可能是“控制台窗口”是一個更熟悉的術語?),它無法顯示Unicode中的所有字符。 要解決這個問題,你需要讓自己擁有一個支持Unicode的終端模擬器,然后確保Python 知道它在支持Unicode的終端模擬器中運行。 如果您不知道如何操作,請在superuser.com上提出一個新問題,指定您的操作系統。

我的終端模擬器可以顯示Unicode中的所有字符,假設所有必需的字體都可用,並且Python知道這一點,所以我可以這樣做而不會得到異常:

>>> with open("countryCity2.json", "r", encoding="utf-16") as f:
...   x = f.read()
... 
>>> print(x)
["Xinhua","Ürümqi"]

但是,這不是你唯一的問題。 您的輸入文件已編碼其編碼。 Ãœrümqi不是任何語言中有意義的字符序列。 但是,它符合已經從遺留編碼轉換為UTF-8的文本的特征mojibake模式,然后 - 錯誤地 - 再次轉換為Unicode編碼。 我們可以通過將它1:1轉換為字節並查看是否獲得有效的UTF-8字節序列來測試它:

>>> print(x.encode("iso-8859-1").decode("utf-8"))
["Xinhua","Ürümqi"]

Ürümqi ”是一個真實的詞,可能與“ 新華 ”一起出現。 此外,如果文本沒有被錯誤轉換為UTF-8,我們會看到一個例外:

>>> "Ürümqi".encode("iso-8859-1").decode("utf-8")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xdc in position 0:
  invalid continuation byte

所以這個假設得到了證實。

在一個必須處理大量文件的程序中,這些文件的編碼可能會或者可能沒有以這種方式被破壞,我會做這樣的事情:

for fname in input_files:
    with open(fname, "r", encoding="utf-16") as f:
        contents = f.read()
    try:
        contents = contents.encode("iso-8859-1").decode("utf-8")
    except (UnicodeEncodeError, UnicodeDecodeError):
        pass
    process_file(fname, contents)

我在這里使用ISO 8859.1編碼並不是因為文本實際上或者實際上是在那個編碼中,而是因為Python的iso-8859-1編解碼器是從字符U + 0000..U + 00FF到字節0x00..0xFF的身份映射。 (從技術上講,這意味着它實現了IANA ISO_8859-1:1987而不是原始的ECMA-94:1985代碼頁,這使得0x00..0x1F和0x7F..0x9F范圍未定義。)即,

>>> "".join(chr(c) for c in range(256)).encode('iso-8859-1') == bytes(range(256))
True

因此,只要您將二進制數據錯誤地轉換為Unicode,就可以使用.encode('iso-8859-1')恢復原始數據。

注意:上面的所有代碼片段都是Python 3。

我的回答是關於Python3.5並且忽略所有maformed caracters,所以objectif是在try塊中打印帶有print的正確caracters,並且在塊中除了你可以在塊中使用pass,或者打印它們並編碼他們用encode()

from codecs import open
with open("C:/test2/trans1", "r", "utf-8") as f:
    lines = f.readlines()
    f.close()
for ligne in lines:
    try:
        print(ligne.rstrip())
    except UnicodeEncodeError:
        print(ligne.rstrip().encode())

暫無
暫無

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

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