日本語の単語境界による分解

日本語のテキストを単語に分解するテストをしてみました。まずは java.text.BreakIterator を試してみました。java.text.spi.BreakIteratorProvider に対して、実際の処理を行うサービスを実装していくことになりますが、今回はデフォルトのままです。


import java.text.BreakIterator;
import java.util.Locale;

public class Test {

  public static void main(String[] args) {
    if (args.length == 1) {
      String stringToExamine = args[0];

      BreakIterator boundary = BreakIterator.getWordInstance(Locale.JAPANESE);
      boundary.setText(stringToExamine);
      int start = boundary.first();
      for (int end = boundary.next();
        end != BreakIterator.DONE;
        start = end, end = boundary.next()) {
        System.out.println("[" + stringToExamine.substring(start, end) + "]");
      }
    }
  }

}

引数に日本語文字列を渡すと、単語境界 (というか文字種の変わり目) にて分解されます。


$ java Test コーヒーは、コーヒー豆を焙煎し挽いた粉末を、湯または水で成分を抽出した飲料のこと。
[コーヒー]
[は]
[、]
[コーヒー]
[豆]
[を]
[焙煎]
[し]
[挽]
[いた]
[粉末]
[を]
[、]
[湯]
[または]
[水]
[で]
[成分]
[を]
[抽出]
[した]
[飲料]
[のこと]
[。]

※ 例文は Wikipedia 日本語版のコーヒーの項目から引用

文字種の境界での区切り方は、処理としては軽いですし、悪くないとは思います。が、[挽][いた] は [挽いた] で捉えたいところです。辞書によるアプローチが必要となります。

Java 6 の java.text パッケージ以下のソースを見ると、RuleBasedBreakIterator を継承した DictionaryBasedBreakIterator が見つかり、IBMICU4J (International Components for Unicode for Java) に由来するコードが含まれています。ちょっと期待してリソース中の /sun/text/resources の辞書まで追い掛けてみましたが、日本語については手付かずの状態のようです。

森田::