2017-07-14 23 views
1

在我的應用程序,用戶可以上傳文件(文本文件),我需要閱讀並構建JSON對象另一個API調用。BOM字符複製到JSON在Python 3

我打開與

f = open(file, encoding="utf-8") 

文件中獲得的第一個字,構建JSON對象,...

我的問題是,一些文件(特別是來自微軟環境)有BOM對象開頭。問題是我的Json現在有這個字符

{ 
    "word":"\\ufeffMyWord" 
} 

當然,從這一點API不工作。

我顯然錯過了什麼,因爲,不應該UTF-8 BOM刪除對象? (因爲它不是utf-8-sig)。

如何克服呢?

回答

3

否,UTF-8標準沒有定義一個BOM字符。這是因爲UTF-8沒有像UTF-16和UTF-32這樣的字節順序模糊問題。 Unicode協會不建議使用U + FEFF在UTF-8編碼的文件的開頭,而IETF積極鼓勵它,如果替代指定編解碼器存在。從Wikipedia article on BOM usage in UTF-8

Unicode標準允許使用UTF-8的BOM,但不要求或推薦使用它。

[...]

的IETF建議,如果一個協議或者(a)始終使用UTF-8,或(b)具有一些其它方式來指示正在使用什麼編碼,然後將其「應該禁止使用U + FEFF作爲簽名。「

Unicode標準只'允許'BOM,因爲它是一個常規字符,就像任何其他;這是一個零寬度的不間斷空格字符。因此,Unicode聯盟建議在解碼時不要刪除,以保留信息(如果它有不同的含義或者您希望保留與依賴它的工具的兼容性)。

你有兩個選擇:

  • 地帶的字符串第一,U + FEFF被認爲是空白與str.strip()所以去除。或明確剛剛剝離BOM:

    text = text.lstrip('\ufeff') # remove the BOM if present 
    

    (技術上說會移除任何數量的零寬度不間斷空格字符,但是這可能是你無論如何要什麼)。

  • 打開與utf-8-sig編解碼器,而不是文件。該編解碼器被添加來處理這些文件,在解碼之前明確地從開始刪除UTF-8 BOM字節序列(如果存在的話)。它將處理沒有這些字節的文件。

+0

很酷,我不知道'utf-8-sig'接受沒有BOM的輸入。 – lenz

-1

UTF-8沒有消除BOM(字節順序標記)。您必須檢查文件是否包含BOM,並將其刪除。

if text.startswith(codecs.BOM_UTF8): 
    headers[0] = (headers[0])[3:] 
    print "Removed BOM" 
else: 
    print "No BOM char, Process your file" 
+0

這隻適用於**字節串**。請注意,OP使用的是Python 3,而不是Python 2,並且*已經解碼了數據*。 –

+0

換句話說,它們的文本以單個代碼點「\ ufeff''開始,而不是以3個字節的'b'\ xef \ xbb \ xbf''開頭。 –