C# 外部ライブラリを使わずに半角→全角カタカナ変換
C#で半角カタカナを全角に変換する必要が出てきて、ネットで調べてみたらVB.NETの関数や他のライブラリを使って変換する方法が多いようです。
なんとなくしたくないから、試行錯誤しながらなんとかできるようになりました。
TL;DR
簡単に言えば、半角と全角の辞書を作って正規表現でマッチするだけですが、正規表現を使うときに罠があって試行錯誤しました。
辞書を作るといえば、力仕事のように聞こえますが、Excelで簡単に作れますし、一回作っておけばずっと使えるから別に手間だと思いませんでした。
目次
半角→全角カタカナの辞書を作る
Excelで辞書の本体を簡単に作る
Excelで全角のアだけ入力して、その他は全部数式で自動生成します。
こんな感じになります:
ExcelからC#ソースにコピペして辞書完成
長いので折りたたんでおきます。
コードはこちらです。
Dictionary<string,string> dictKatakana = new Dictionary<string, string> () {
{"ア","ア"},
{"ィ","ィ"},
{"イ","イ"},
{"ゥ","ゥ"},
{"ウ","ウ"},
{"ェ","ェ"},
{"エ","エ"},
{"ォ","ォ"},
{"オ","オ"},
{"カ","カ"},
{"ガ","ガ"},
{"キ","キ"},
{"ギ","ギ"},
{"ク","ク"},
{"グ","グ"},
{"ケ","ケ"},
{"ゲ","ゲ"},
{"コ","コ"},
{"ゴ","ゴ"},
{"サ","サ"},
{"ザ","ザ"},
{"シ","シ"},
{"ジ","ジ"},
{"ス","ス"},
{"ズ","ズ"},
{"セ","セ"},
{"ゼ","ゼ"},
{"ソ","ソ"},
{"ゾ","ゾ"},
{"タ","タ"},
{"ダ","ダ"},
{"チ","チ"},
{"ヂ","ヂ"},
{"ッ","ッ"},
{"ツ","ツ"},
{"ヅ","ヅ"},
{"テ","テ"},
{"デ","デ"},
{"ト","ト"},
{"ド","ド"},
{"ナ","ナ"},
{"ニ","ニ"},
{"ヌ","ヌ"},
{"ネ","ネ"},
{"ノ","ノ"},
{"ハ","ハ"},
{"バ","バ"},
{"パ","パ"},
{"ヒ","ヒ"},
{"ビ","ビ"},
{"ピ","ピ"},
{"フ","フ"},
{"ブ","ブ"},
{"プ","プ"},
{"ヘ","ヘ"},
{"ベ","ベ"},
{"ペ","ペ"},
{"ホ","ホ"},
{"ボ","ボ"},
{"ポ","ポ"},
{"マ","マ"},
{"ミ","ミ"},
{"ム","ム"},
{"メ","メ"},
{"モ","モ"},
{"ャ","ャ"},
{"ヤ","ヤ"},
{"ュ","ュ"},
{"ユ","ユ"},
{"ョ","ョ"},
{"ヨ","ヨ"},
{"ラ","ラ"},
{"リ","リ"},
{"ル","ル"},
{"レ","レ"},
{"ロ","ロ"},
{"ヮ","ヮ"},
{"ワ","ワ"},
{"ヰ","ヰ"},
{"ヱ","ヱ"},
{"ヲ","ヲ"},
{"ン","ン"},
{"ヴ","ヴ"},
{"ヵ","ヵ"},
{"ヶ","ヶ"},
{"ー","ー"}
};
変換関数を作る
試行錯誤
!注意:このセクションに間違ったコードがあります!
public string HalfToFullKatakana(string input)
{//このコードは間違っています。使用しないでください。
Regex re = new Regex(@"[\uFF61-\uFF9F]");
//半角カタカナを表す正規表現
string output = re.Replace(input, match =>
{//Matchした場合の処理
if (dictKatakana.ContainsKey(match.Value))
{//辞書にあれば辞書にある値を返す
return dictKatakana[match.Value];
}
else
{//辞書になければつまり半角カタカナでなければ変換せずに返す
return match.Value;
}
});
return output;
}
一見問題がなさそうですが、実施に変換してみます。
string half = "パソコン机にキーボードがある";
string full=HalfToFullKatakana(half);
Console.WriteLine(half);
Console.WriteLine(full);
出力結果は以下です:
パソコン机にキーボードがある
パソコン机にキーボードがある
パ ボ ドの濁点が少し離れている・・・でも私は当時気づきませんでした(笑)。
変換された文字が検索機能に使われたので、検索しても当たらないからはじめて気づきました。
半角カタカナの濁点は別文字になっているから、正規表現で一部しかマッチしていないからこうなったと分かりました。例えば、
パ
はハ
と゚
で出来ています。正規表現で辞書を引いたときは、ハ
がマッチされて、全角のハ
が返されますが、濁点゚
はマッチされないので、そのまま返されるので、パ
という変な組み合わせになってしまいます。
間違いを修正して完成
public string HalfToFullKatakana(string input)
{//これは修正されたバージョンです。
Regex re = new Regex(@"[ヲ-ン]゙|[ヲ-ン]゚|[ヲ-ン]");
//↑ここだけ修正
string output = re.Replace(input, match =>
{//Matchした場合の処理
if (dictKatakana.ContainsKey(match.Value))
{//辞書にあれば辞書にある値を返す
return dictKatakana[match.Value];
}
else
{//辞書になければつまり半角カタカナでなければ変換せずに返す
return match.Value;
}
});
return output;
}
修正したのは一カ所だけです:
Regex re = new Regex(@"[ヲ-ン]゙|[ヲ-ン]゚|[ヲ-ン]");
正規表現のパターンを変えました。この3種類の順番が重要です。
濁点のついている半角カタカナを先にマッチさせればいいです。
修正後の結果出力:
パソコン机にキーボードがある
パソコン机にキーボードがある
濁点は元に戻りました~
この方法は意外とシンプルすぎて大丈夫かなと少し不安でしたが、数ヶ月使ってきて、今のところ問題がなさそうです。
何か思い及ばないところでバグるかもしれないので、留意しながら使っていきたいと思います。
コメント
コメントを投稿
個人情報を記入しないようご注意ください