【Java】 表記ゆれを考える

はじめに

 表記ゆれを補正するプログラムを考える。
  => 結論から言うと、簡単にできる代物じゃない...(流石にこの分野だけで研究されているだけはある...)
  => 全てに対応するのは大変なので、カタカナ単語のみを考える
  => 基本的なもの以外は、後からカスタマイズして対応できるような作りにしておく

サンプル

ただ、これだと実用できない(詳細は下記「適用できないケース」を参照)
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;

public class OrthographicVariantsUtils {
  private static final String FORMAT_FOR_REMOVE_LAST = "{0}$";
  private static final String LONG_VOWEL = "ー";
  private Map<String, String> convertMapper;

  public OrthographicVariantsUtils() {
    this.convertMapper = new HashMap<String, String>() {
      private static final long serialVersionUID = 1L;
      {
        put("ヴァ", "バ");
        put("ヴィ", "ビ");
        put("ヴゥ", "ブ");
        put("ヴェ", "ベ");
        put("ヴォ", "ボ");
      }
    };
  }

  public static void main(String[] args) {
    OrthographicVariantsUtils instance = new OrthographicVariantsUtils();

    // 単語を登録
    instance.registWord("ダイア", "ダイヤ");

    System.out.println(instance.revise("サーバー"));
    System.out.println(instance.revise("メモリー"));
    System.out.println(instance.revise("ダイアモンド"));
    System.out.println(instance.revise("ヴァイオリン"));
  }

  public String revise(String targetValueInKatakana) {
    String returnValue = targetValueInKatakana;

    // 登録されている単語に置き換える
    for (Map.Entry<String, String> entry : this.convertMapper.entrySet()) {
      returnValue = returnValue.replaceAll(entry.getKey(), entry.getValue());
    }

    // 語尾の長音「ー」を削除
    return removeLast(returnValue, LONG_VOWEL);
  }

  public String registWord(String word, String fixedWord) {
    return this.convertMapper.put(word, fixedWord);
  }

  private static String removeLast(String textValue, String regex) {
    if (textValue == null) {
      return null;
    }
    return textValue.replaceFirst(MessageFormat.format(FORMAT_FOR_REMOVE_LAST, regex), "");
  }
}

出力結果

サーバ
メモリ
ダイヤモンド
バイオリン

適用できないケース

 * 語尾の長音「ー」を無条件で削除しているが、「ピッチャー」など、削除してはいけないケースもある

その他もろもろ...

結論

 * 仕様が限定されていなければ、以下の関連記事などで記載されているフリーツールなどを検討して使った方がいい
http://blogs.yahoo.co.jp/dk521123/36655532.html

メモ

 * 動的計画法(Dynamic Programming, DP)を使う(最長共通部分列問題の応用?)のも手らしいのだが...
http://blogs.yahoo.co.jp/dk521123/36662096.html

関連記事

Java正規表現 [5] 不要文字除去 / 対象文字のみ抽出 ~ replaceFirst / replaceAll ~

http://blogs.yahoo.co.jp/dk521123/36653535.html

文字列の類似度・レーベンシュタイン距離/ジャロ・ウィンクラー距離 ~ Apache Lucene

http://blogs.yahoo.co.jp/dk521123/36655532.html