日本語文字コード判定、ICUを使ってみた。
文字コードの自動判定について調べていたらコチラの記事を見つけました。
日本語文字コード認識のテストレポートらしい - てきとうなメモ
libguess 0.99971(5個)、 ICU 0.9996(6個)、 nkf 0.998567(25個)、 universalchardet 0.969221(537個)
:
日本語限定であればlibguess。 世界各国語が対象なら判定速度は遅いがICUがいい。
なるほど。ということで、ICUを使ったコードを書いてみました。
unicode/ucsdet.hをincludeしてやって、
#include <unicode/ucsdet.h>
こんな感じのコードで、判定できるようです。このコードでは、一致した文字コードを10個まで表示しています。
… UErrorCode error = U_ZERO_ERROR; UCharsetDetector* detector = ucsdet_open(&error); if (U_FAILURE(error)) return NULL; ucsdet_setText(detector, s.c_str(), s.size(), &error); if (U_FAILURE(error)) return NULL; int32_t founded = 0; const UCharsetMatch** matchers = ucsdet_detectAll(detector, &founded, &error); if (U_FAILURE(error)) return NULL; if (founded > 0) { const int32_t kThresold = 10; for (int i = 0; i < founded; ++i) { int32_t confidence = ucsdet_getConfidence(matchers[i], &error); if (U_FAILURE(error)) { error = U_ZERO_ERROR; continue; } if (confidence < kThresold) break; const char* match_encoding = ucsdet_getName(matchers[i], &error); if (U_FAILURE(error)) { error = U_ZERO_ERROR; continue; } const char* match_lang = ucsdet_getLanguage(matchers[i], &error); if (U_FAILURE(error)) { error = U_ZERO_ERROR; continue; } std::cout << " neme:" << match_encoding << " language:" << match_lang << std::endl; } std::cout << "-----" << std::endl; } ucsdet_close(detector); …
ucsdet_detectAllを使用して、文字コード判定を行えます。
また、判定コードがひとつだけでいい場合は、ucsdet_detectを使えば良いようです。
const UCharsetMatch* match = ucsdet_detect(detector, &error); if (U_FAILURE(error)) return NULL; std::cout << " neme:" << ucsdet_getName(match, &error) << " language:" << ucsdet_getLanguage(match, &error) << std::endl;