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";

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

2 則留言:

jserv 提到...

Fixed now.
http://blog.linux.org.tw/~jserv/archives/001672.html

匿名 提到...

jserv 的這個很好用喔~
算算大小 so 的部份是 168k
example 的部份才 12k

[Windows] git-bash 底下的工具

因為工作轉到 Windows 平台上的關係,所以很多工具改到 Windows 上面運作,跟著在 TortoiseGit 底下使用 git-bash 來維護自己的專案原始碼。結果就是裝了前面提過的 auto-hotkey 使用熱鍵來提昇自己的平台操作速度; 但除了 hotkey...