1. 程式人生 > >Python讀取文件,使用split進行分割時,出現ufeff

Python讀取文件,使用split進行分割時,出現ufeff

lin replace little 讀取文件 get txt ace tty 連續

1.問題

使用python3.6對文件讀取時,按照正常套路處理,文件內容類似以下:

啊啊啊 || AAA

不不不 || BBB

當使用utf-8讀取文檔並且使用split函數分割時,發現第一行字符分割後,莫名多了一個\ufeff

因為這個原因,導致後續使用 == 或者 x in list 操作時,涉及到第一行的數據時,出錯

Debug第一行見下圖(第二行以後是沒問題的)

技術分享圖片

2.原因

參考1:

The Unicode character U+FEFF is the byte order mark, or BOM, and is used to tell the difference between big- and little-endian UTF-16 encoding

u = u‘ABC‘
e8 = u.encode(‘utf-8‘)        # encode without BOM(沒考慮BOM)
e8s = u.encode(‘utf-8-sig‘)   # encode with BOM(考慮了BOM)
e16 = u.encode(‘utf-16‘)      # encode with BOM
e16le = u.encode(‘utf-16le‘)  # encode without BOM
e16be = u.encode(‘utf-16be‘)  # encode without BOM

參考2

\ufeff是一個特殊的標識,表明編碼方式,

字節序,也就是字節的順序,指的是多字節的數據在內存中的存放順序,在幾乎所有的機器上,多字節對象都被存儲為連續的字節序列,根據信息在連續內存中的存儲順序,字節序被分為大端序(Big Endian)小端序(Little Endian)兩類。( 然後就牽涉出兩大CPU派系:一派如PowerPC 970等處理器采用 Big Endian方式存儲數據,另一派如x86系列等處理器采用Little Endian方式存儲數據)。其中大端序和小端序解釋如下:

  • Big Endian 是指低地址端 存放 高位字節。
  • Little Endian 是指低地址端 存放 低位字節。

對其作用及更多內容見參考

3.解決方法

一種方法:

通過utf-8對字符串進行encode成byte數組,然後再對該byte數組使用utf-8-sig進行decode,即:

    templateList = []
    for line in open(templateResult.txt, encoding=utf-8):
        tmps = line.strip().split(|)
        templateList.append(tmps[0].encode(
            utf-8).decode(utf-8-sig).strip().replace(, ‘‘))

另一種方法,直接使用‘utf-8-sig’打開文件:

    templateList = []
    for line in open(templateResult.txt, encoding=utf-8-sig):
        tmps = line.strip().split(|)
        templateList.append(tmps[0].strip().replace(, ‘‘))

  

4.總結

寫文檔或者讀文檔是python經常用到的操作,如使用open(‘test.txt‘,encoding=‘utf-8‘)的方式打開文檔,當在處理第一行數據的時候可能由於自己忽略導致問題。

本文對出錯的原因及解決辦法進行了說明。

參考

https://stackoverflow.com/questions/17912307/u-ufeff-in-python-string

https://songlee24.github.io/2015/05/02/endianess/

Python讀取文件,使用split進行分割時,出現\ufeff