2015/04/03

[C#]全角数字/アルファベットを半角に変換する

このエントリーをはてなブックマークに追加
全角の数字、全角のアルファベットを半角に変換したいなー、と思った。
全角英数はもっさりしてて読みにくい。
なんか、いかにも一発でできるメソッドが用意されてそうなのだけどないらしい。
なので自力でコードを書きました。

全角数字、全角アルファベットを半角にする


変換テーブルを作って自作することにします。
がっつり組んで、がりがり動かしているだけなので、種も仕掛けもありません。

書いたのは、見本となるテキストの文字を走査して、変換テーブルと照らし合わせて置換していくというコードです。
もしくは、変換テーブルのほうを走査してReplaceしていくようなコードも書けそうです。今回は1文字づつの走査でいいので前者のほうが効率よさそうですね。

使う文章
※たまたま拾ってきたニュース記事です。他意はありません。
一方、日本で「VAIO Phone」が正式に発表された際、パナソニックのスマホ「ELUGA U2」と「ロゴが違うだけではないか」、「ELUGA U2のコピーに近いにもかかわらず、価格はELUGA U2より高い」などと批判の声があがったことを伝えた。
「VAIO Phone」の販売出だしつまづく・・・「惨敗としか表現できない」=中国
http://headlines.yahoo.co.jp/hl?a=20150402-00000179-scn-sci

ソースコード
string text =
    "一方、日本で「VAIO Phone」が正式に発表された際、" +
    "パナソニックのスマホ「ELUGA U2」と「ロゴが違うだけ" +
    "ではないか」、「ELUGA U2のコピーに近いにもかかわら" +
    "ず、価格はELUGA U2より高い」などと批判の声があがっ" +
    "たことを伝えた。";

// 変換テーブルをつくる
Dictionary conv = new Dictionary() {
    {'1','1'},{'2','2'},{'3','3'},{'4','4'},{'5','5'},
    {'6','6'},{'7','7'},{'8','8'},{'9','9'},{'0','0'},
    {'A','A'},{'B','B'},{'C','C'},{'D','D'},{'E','E'},
    {'F','F'},{'G','G'},{'H','H'},{'I','I'},{'J','J'},
    {'K','K'},{'L','L'},{'M','M'},{'N','N'},{'O','O'},
    {'P','P'},{'Q','Q'},{'R','R'},{'S','S'},{'T','T'},
    {'U','U'},{'V','V'},{'W','W'},{'X','X'},{'Y','Y'},
    {'Z','Z'},
    {'a','a'},{'b','b'},{'c','c'},{'d','d'},{'e','e'},
    {'f','f'},{'g','g'},{'h','h'},{'i','i'},{'j','j'},
    {'k','k'},{'l','l'},{'m','m'},{'n','n'},{'o','o'},
    {'p','p'},{'q','q'},{'r','r'},{'s','s'},{'t','t'},
    {'u','u'},{'v','v'},{'w','w'},{'x','x'},{'y','y'},
    {'z','z'},
    {' ',' '},
};

string s = new string( text.Select( n => (conv.ContainsKey(n) ? conv[n] : n )).ToArray() );

Console.WriteLine(s); // 出力結果を表示

出力結果
一方、日本で「VAIO Phone」が正式に発表された際、パナソニックのスマホ「ELUGA U2」と「ロゴが違うだけではないか」、「ELUGA U2のコピーに近いにもかかわらず、価格はELUGA U2より高い」などと批判の声があがったことを伝えた。

いいじゃん! そんでVAIO Phoneがなんですって?
ニュースのネタの内容についてはあんまりわかりませんが、ずいぶんと読みすくなったね。

string s = new string( text.Select( n => (conv.ContainsKey(n) ? conv[n] : n )).ToArray() );
結局、主要コードはこの1行なので、ざっと。
  1. Selectでtextを一文字づつ走査。
  2. conv.ContainsKey(n) ? conv[n] : n で変換テーブルに該当したのを返す。
  3. ToArray()でchar[]にして、new string(char[])でstringが返ります。

置換対象は全角数字と全角アルファベット(大文字/小文字)、あと全角スペースの計63文字(10+26+26+1)としています。
全角スペースについては、先頭に来るやつは新しい段落としての意味があるので単純置換はまずいですね。

ConvStrを使って変換するやりかた


文字列を全角/半角に変換するには?(VB.NET関数活用)
http://www.atmarkit.co.jp/fdotnet/dotnettips/265vbhanzen/vbhanzen.html

Strings.StrConvでは、全角カタカナも半角カタカナになってしまうようで、なんていうか、やりすぎなのです。
半角カタカナなんて使う場面はもうないのです。

Strings.StrConvを使うには、Microsoft.VisualBasicの参照が必要です。

ソースコード
// using Microsoft.VisualBasic;

string text =
    "一方、日本で「VAIO Phone」が正式に発表された際、" +
    "パナソニックのスマホ「ELUGA U2」と「ロゴが違うだけ" +
    "ではないか」、「ELUGA U2のコピーに近いにもかかわら" +
    "ず、価格はELUGA U2より高い」などと批判の声があがっ" +
    "たことを伝えた。";

string s = Strings.StrConv(text, VbStrConv.Narrow, 0);

Console.WriteLine(s);

出力結果
一方、日本で「VAIO Phone」が正式に発表された際、パナソニックのスマホ「ELUGA U2」と「ロゴが違うだけではないか」、「ELUGA U2のコピーに近いにもかかわらず、価格はELUGA U2より高い」などと批判の声があがったことを伝えた。

パナソニックのスマホて。なんか、すごいおちょぼ口な感じ。

正規表現を使ったやりかた


正規表現を使ったやりかたもあります。
すべてにStrings.StrConvするのではなくて、該当文字だけがStrings.StrConvの恩恵を受ければいいじゃないかという考え方ですね。

全角英数字のみを半角に変換するには?[C#、VB]
http://www.atmarkit.co.jp/fdotnet/dotnettips/1051anhankaku/anhankaku.html

おしまいですー。

0 件のコメント :

コメントを投稿