語言:pythonhtml
編程工具:pycharmpython
硬件環境:win10 64位編程
讀取文件過程當中發現一個問題:已有記事本文件(非空),轉碼 UTF-8,複製到pycharm中,在開始位置打印結果會出現 \ufeff, 打印代碼以下瀏覽器
f = open('new2.txt', encoding='UTF-8') # 打開文件,以 UTF-8 編碼 l = [] for line in f: l.append(line.strip()) print(l)
打印結果爲:app
只需改一下編碼就行,把 UTF-8 編碼 改爲 UTF-8-sig編程語言
f = open('new2.txt', encoding='UTF-8-sig') l = [] for line in f: l.append(line.strip()) print(l)
打印結果爲:編輯器
utf-8與utf-8-sig兩種編碼格式的區別:工具
As UTF-8 is an 8-bit encoding no BOM is required and anyU+FEFF character in the decoded Unicode string (even if it’s the firstcharacter) is treated as a ZERO WIDTH NO-BREAK SPACE.post
UTF-8以字節爲編碼單元,它的字節順序在全部系統中都是一様的,沒有字節序的問題,也所以它實際上並不須要BOM(「ByteOrder Mark」)。可是UTF-8 with BOM即utf-8-sig須要提供BOM。ui
關於 \ufeff 的一些資料(引自維基百科):
字節順序標記(英語:byte-order mark,BOM)是位於碼點U+FEFF
的統一碼字符的名稱。當以UTF-16或UTF-32來將UCS/統一碼字符所組成的字符串編碼時,這個字符被用來標示其字節序。它常被用來當作標示文件是以UTF-八、UTF-16或UTF-32編碼的記號。
字符U+FEFF若是出如今字節流的開頭,則用來標識該字節流的字節序,是高位在前仍是低位在前。若是它出如今字節流的中間,則表達零寬度非換行空格的意義,用戶看起來就是一個空格。從Unicode3.2開始,U+FEFF
只能出如今字節流的開頭,只能用於標識字節序,就如它的名稱——字節序標記——所表示的同樣;除此之外的用法已被捨棄。取而代之的是,使用U+2060
來表達零寬度無斷空白。
在UTF-16中,字節順序標記被放置爲文件或字符串流的第一個字符,以標示在此文件或字符串流中,以全部十六比特爲單位的字碼的尾序(字節順序)。
0xFE
,其後跟着0xFF
(其中的0x
用來標示十六進制)。0xFF
,其後接着0xFE
。而統一碼中,值爲U+FFFE
的碼位被保證將不會被指定成一個統一碼字符。這意味着0xFF
、0xFE
將只能被解釋成小尾序中的U+FEFF
(由於不多是大尾序中的U+FFFE
)。
UTF-8則沒有字節順序的議題。UTF-8編碼過的字節順序標記則被用來標示它是UTF-8的文件。它只用來標示一個UTF-8的文件,而不用來講明字節順序。[1]許多視窗程序(包含記事本)會添加字節順序標記到UTF-8文件。然而,在類Unix系統(大量使用文本文件,用於文件格式,用於進程間通訊)中,這種作法則不被建議採用。由於它會妨礙到如解譯器腳本開頭的Shebang等的一些重要的碼的正確處理。它亦會影響到沒法識別它的編程語言。如gcc會報告源碼檔開頭有沒法識別的字符。而在PHP中,若是沒有激活輸出緩衝(output buffering),它會使得頁面內容開始被送往瀏覽器(即:用戶頭文件已被提交),這使PHP腳本沒法指定用戶頭文件(HTTP Header)。字節順序標記在UTF-8中被表示爲序列EF BB BF
,對大部分未準備好處理UTF-8的文本編輯器及網頁瀏覽器而言,在ISO-8859-1的環境中則會顯示
。
雖然字節順序標記亦能夠用於UTF-32,但這個編碼不多用於傳輸,其規則如同UTF-16。對於已於IANA註冊的字符集UTF-16BE、UTF-16LE、UTF-32BE和UTF-32LE等來講,不可以使用字節順序標記。文檔開頭的U+FEFF會被解釋成一個(已捨棄的)"零寬度無斷空白",由於這些字符集的名字已決定了其字節順序。對於已註冊字符集UTF-16和UTF-32來講,一個開頭的U+FEFF則用來表示字節順序。