[Python] 使用 chardet 偵測字串的編碼

[Python] 使用 chardet 偵測字串的編碼

最近專案需要把一個檔名,從未知的編碼轉成 Unicode 處理…

為什麼會有未知的編碼呢?

因為檔案名稱可能是從中文 Windows 用 winscp 直接拖到 Linux 上去的 (那就會是 BIG5),

或是從郵件中解出來的檔名 (那有可能是 UTF-8 或是寄件者設定的郵件編碼),

或是從其他拉拉雜雜的不明來源取得的檔名…

 

這樣的檔名要處理起來很困難,

當拿到一個中文 BIG5 編碼的字串,卻用日文 SHIFT-JIS 來解譯的話,

最後要嘛是呈現上出現怪怪的字,要嘛還會出現其他的災難…

問題是,要怎麼用 python 知道任意字串的編碼呢?

 

事實上是沒有完美的解法,

Google 一下就可以看到一堆人在求問,然後也有一堆人在解釋,

因為同樣的 bytes 在 BIG5 裡是合法字元,在 SHIFT-JIS, GBK… 等等,

可能都是合法字元,所以根本分不出來…

不過雖然沒有完美的解法,網路上還是有不少套件幫忙「猜」字串的編碼,

還是可以試試看的~

 

chardet 是蠻多人建議使用的 python 套件,使用上也很簡單:

 

1. 使用 pip 安裝 chardet

如果 pip 還沒有安裝的話,參考一下 pip installation 這邊,

然後執行下面的指令,就可以裝好 chardet 套件了~

sudo pip install chardet

 

2. 執行 chardet

執行 chardet.detect() 函式就可以偵測字串「最有可能」的編碼~

>>> import chardet
>>> chardet.detect("this is english")
{'confidence': 1.0, 'encoding': 'ascii'}
>>> chardet.detect('\xa4\xa4\xa4\xe5\xa4\xa4')
{'confidence': 0.5, 'encoding': 'windows-1252'}
>>> chardet.detect('\xa4\xa4\xa4\xe5\xa4\xa4\xa4\xe5')
{'confidence': 0.99, 'encoding': 'Big5'}

 

基本上如果給的字串越長,猜出來的準確度就越高~

像上例中,我給了「中文中」三個字的時候猜成了 windows-1252,

給了「中文中文」四個字的時候,就正確的猜到了 BIG5 了~

 

 chardet.detect() 還會提供信心指數作參考…

不過真的只是參考, 我就遇過日文字串偵測為 SHIFT-JIS 的信心指數只有 20%,

可是中文字串偵測為 windows-1252 (幾乎所有 0~255 都是合法的編碼,只有少數不是) 的信心指數卻有 50%…

還有一次是日文字串完全偵測不出編碼,encoding 的值變成 None 了…

不過,畢竟還是一個可以參考的工具,就看如何使用了~

 

PS: 有些套件是號稱比 chardet 速度快的 (沒試過),但似乎都有些限制,

像是 cchardet 需要使用 cython,

而 fastchardet 只支援 ASCII, UTF-8, windows-1252,算是少的可憐…

 

 

(本頁面已被瀏覽過 1,562 次)

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。

這個網站採用 Akismet 服務減少垃圾留言。進一步瞭解 Akismet 如何處理網站訪客的留言資料