2007/08/29

[Programming] 自動偵測編碼

有參考到 Tsung 的 blog 裡頭寫到的 php.net 上的 function ,不過顯然還不大行:
$str ="中文測試";
echo mb_detect_encoding($str)."\n";
$str = iconv("utf8","big5","中文測試");
echo mb_detect_encoding($str)."\n";
echo $str."\n";

執行下去你就知道了... 對我們而言,偵測最重要的就是分出 utf8 跟 big5 的差別。
但是連這麼單純的字串都分辨不出來,就不用提後面的部份了。
所以 php 應該先淘汱掉(?) *註

然後 Ticore提到另外兩個工具,結果他已經寫了出來。

用Google一找,找到兩個
分別是 Chinese Encoding Guesser 與 Mozilla charset detector
後者就是 Mozilla 在用的編碼檢測 Java 版

試用的結果 前者效果似乎不錯
但是它只會得到一個偵測結果
而 Mozilla 版的效果欠佳
尤其是 Big5 編碼偵測結果幾乎都錯
難怪 Mozilla、Firefox 瀏覽器自動偵測效果不好.....

不過它的特色是幾乎涵蓋大部分編碼種類
而且猜測的結果不只一個
也可以預設猜測的語言種類

這兩種都可以針對位元陣列、檔案或者是一個URL來作偵測

不過 Java 的部份我不熟,所以先行跳過。

Jserv之前也有提過一個 pcmanx 的 addon:

我初步將 NSPR (Mozilla Runtime) 一類的包袱去掉,並且用 G++ 的 -fno-rtti、-fno-exceptions,以及 -nostdinc++ compilation flags 來編譯 ,如果將 -lstdc++ 換成 -lsupc++,還可進一步得到 C-only library,目標是作成一個 add-on,讓 [PCManX] 可透過 dlopen 來操控內部實做,初步完成自動偵測文件編碼與測試程式,名為 [charset-detector] (bzip2 tarball)。


不過在 make 的時候出了問題:
nsSBCSGroupProber.cpp:(.text+0x18f): undefined reference to `free'
/usr/bin/ld: .libs/chardetect.so: hidden symbol `free' isn't defined
/usr/bin/ld: final link failed: Nonrepresentable section on output
collect2: ld returned 1 exit status
make: *** [chardetect.la] Error 1


看起來是 linker 在 libstdc++ 上找不到 free ?
不過不懂為什麼,所以還是沒得用。

最後用到 python-chardet
>>> import urllib
>>> rawdata = urllib.urlopen('http://yahoo.co.jp/').read()
>>> import chardet
>>> chardet.detect(rawdata)
{'encoding': 'EUC-JP', 'confidence': 0.99}

import glob
from charset.universaldetector import UniversalDetector

detector = UniversalDetector()
for filename in glob.glob('*.xml'):
print filename.ljust(60),
detector.reset()
for line in file(filename, 'rb'):
detector.feed(line)
if detector.done: break
detector.close()
print detector.result


不過,這個工具還是有問題....
我丟 Big5 進去,它會回 ASCII....

所以這部份還是很麻煩....

--
更新:
參看過這篇之後,把 encoding_list 再修了一下順序:
function detectCharset($str){
$encoding_list = 'ASCII, BIG5, EUC-CN, UTF-8';
return mb_detect_encoding($str, $encoding_list);
}
$str ="中文測試";
echo detectCharset($str)."\n";
$str = iconv("utf8","big5","中文測試");
echo detectCharset($str)."\n";

現在測試出來的結果應該是這個最能滿足,暫時先用這個看看...
張貼留言

[Windows] 好用的小工具: AutoHotKey

做為一個 Linux 的愛好者,轉移到 Windows 上面的時候,往往難以適應 Windows 調整快捷鍵的方式,所以 google 了一下,結果發現很多人愛用的 "Auto Hot key"。不多說,就來給一個範例說明如何使用 Auto Hot key 來...