半角のローマ字を全角の日本語に変換したいのですが、そういうAPIはありますでしょうか?「nihongo→日本語」みたいな感じです。
IMEを操作するAPIに半角ローマ字を投げて結果を返してもらうような事は出来ないかと思って調べているのですが、見当たらなくて…
やはりそういうのは無いのでしょうか?
nihongo→にほんご までならさほどに難しくないけども、
さらに漢字にとなると、同音異義語をどうします?
shouka→しょうか→消化? 消火? 商家? 昇華? 唱歌?
ここらへんちゃんとしとかんと先に進めません。
>同音異義語をどうします?
あー!なるほど、それがありましたかorz
たまたまテストに使っていた文字に同音異義語が無かっため、うっかりしてました。
(そのせいで検索してもサンプルとか実際にやっている人が見当たらなかったのかな?)
ただ今回特にデータの正確性が求められないので、同音異義語は化けてしまっても構いません。例えばIMEで最初の候補に変換してもらえれば十分です。上の場合だと「消化」にさえ変換できればOKと言った感じです。
そこまでいかなくても「にほんご」にまで変換できれば十分かもしれませんので、よろしかったらその方法だけでも教えて頂けないでしょうか?
ちなみに現在作成しているプログラムですが、あるフォルダ以下にある全てのフォルダ名とファイル名(全部ローマ字)を日本語に変換すると言うものです。何ぶん数が多い(数万個)上に全部ローマ字のため、一度プログラムで全更新した後に、まずいものは手動でファイル名を変更したいと考えています。
> そこまでいかなくても「にほんご」にまで変換できれば十分かもしれませんので、よろしかったらその方法だけでも教えて頂けないでしょうか?
まずいのは手直ししていい(完璧を期さない)なら表を引くだけじゃねぇですか?
"a"→"あ", "i"→"い" ... って対応表を用意しておき、入力ローマ字文字列の
アタマっから表を引きつつ変換すれば。
数が多くても、変換するべきパターン数が少なければ、あえて汎用性を求めずとも、
そのパターンに特化したテーブルでも作れば簡単に実現できそうですが、
そこまで単純な話でもないですか?
例えば、
nekoshashin001 => 猫写真001
nekoshashin002 => 猫写真002
...
nekoshashin999 => 猫写真999
fuukeishashin001 => 風景写真001
なら、「neko => 猫」、「fuukei => 風景」、「shashin => 写真」というパターン
からなるテーブルがあれば事足ります。
もっとも、「yousan => 養蚕」、「shou => 省」、「you => 要」、「sanshou => 参照」
なんてパターンがあって、「yousanshou」というファイル名があれば簡単に破綻して
しまいます(養蚕省? 要参照? 要san省?)ので、ホントに単純なパターン限定になってしまいますが。
# 最長一致するものを優先的に、とか回避策は考えられますが、そこでいろいろ考えるよりは
# 当初の方針通り汎用的な方法を採った方がいいかも。
あ、すみません、IME等を利用することを前提に考えてましたので、ちょっと言葉が足りなかったようですm(__)m
>nihongo→にほんご までならさほどに難しくないけども、
これは単に変換テーブルを用意すると言う話だったのですね。で、あれば了解しました。とりあえず最終手段として考えております。
で、私の中では勝手にIMEを利用して「nihongo→にほんご」に変換できると解釈していたのですが、結局そういう方法はないのでしょうか?
>変換するべきパターン数が少なければ
残念ながらパターンが無数にあります(無数はちょっと大げさですが)。
>当初の方針通り汎用的な方法
それでこちらを探っているのですが、結局変換テーブルを用意する以外に、「IME等を利用するような簡単で汎用的な方法は無い」という結論でよいのでしょうか?
ImmGetConversionListに"nihongo"を突っ込んだら2番目の候補に"にほんご"が帰ってきたよ
初めは候補数1で"nihongo"しか帰ってこなかったけど
いつの間にか候補数2で"nihongo"と"にほんご"が帰ってくるようになった…(汗
実験中…
なぜか"nihongo"以外はだめなのに
"nihongo"だけはひらがな変換結果が返ってくるようになった…
ImmGetConversionListがローマ字入れるとひらがな返したり、元の文字しか返さなかったりとよくわからないどうさなので別の方法で漢字変換だけやってみた。
これが正しい方法かはわからないけれど…
いくつか変換してみたらこうなった
"nihongo"→"日本語"
"日本語"→"日本語"
"hiragana"→"ひらがな"
"nannndeyanenn"→"何でや年"
"hankaku space ari"→"半角 s派セ あり"
LPSTR toKanji(LPSTR roman)
{
// 入力コンテキスト作成
HIMC hIMC;
hIMC = ImmCreateContext();
// IME ON
ImmSetOpenStatus(hIMC,TRUE);
// 変換モード設定
ImmSetConversionStatus(
hIMC,
IME_CMODE_NATIVE | IME_CMODE_FULLSHAPE | IME_CMODE_ROMAN,
IME_SMODE_AUTOMATIC
);
// 変換元文字列設定
ImmSetCompositionString(hIMC,
SCS_SETSTR,
NULL,
0,
roman,
strlen(roman)
);
// 変換実行
ImmNotifyIME(hIMC, NI_COMPOSITIONSTR, CPS_CONVERT, 0);
// 必要サイズ取得
DWORD dwLen = 0;
dwLen = ImmGetCompositionString(hIMC,
GCS_COMPSTR,
NULL,
0
);
// 変換結果取得
LPSTR kanji = (LPSTR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwLen + 1);
ImmGetCompositionString(hIMC,
GCS_COMPSTR,
kanji,
dwLen + 1
);
// 入力コンテキスト破棄
ImmDestroyContext(hIMC);
return kanji;
}
ちなみにWindowsXPProSP2、IME2002で試しました。
ほかのOSや他のIME(ATOK等)でも動くかは自分で試してみてください。
当然、実行マシンの辞書の学習結果によっても結果はかわってくると思います。
それと、ImmGetCompositionStringは変換文字列のみ帰してきて
NULL文字はつけてくれないので要注意
すみません、返答遅れました。
さっそくやってみたのですが、なぜか何も返ってきません(正確には長さ0の文字列が返るようです)。一度じゃ駄目なのかと思い何度かやってみたのですが同じでした。ソースはそのままコピペで使っていて、nihongoやaiueoとかで試しています。
ちなみにこちらの環境は以下です。
WindowsXPProSP2、IME2002
.NET2003、コンソールアプリ、非MFC
何か環境依存の問題があるのですかね…
もう少し色々試してみます。
ウインドウ作ってウインドウプロシージャ内から呼ぶと動くね
編集 削除なるほど、そういう理由でしたか。早速既存のソースをウィンドウベースに変更して実行してみましたが、確かに上手く変換できました。
ちなみに変換の正確性については50%を切るぐらいで微妙な所でしたが(完璧なのは30%ぐらいかも)、それでも5万件近いファイル名を全部手書きで修正するよりは、例え30%でも自動で変換してくれた方がはるかに楽ですので非常に助かりました。
皆さん、どうも有難うございましたm(__)m