全角 / 半角の変換には Microsoft.VisualBasic 名前空間の Strings.StrConv メソッドがよく使われているようですが、それは使わないで、全角数字を半角に変換する方法を書きます。
基本的には Regex.Replace メソッド (String, MatchEvaluator) を使って文字列の中の全角数字の部分を半角数字に置き換えるのですが、問題は引数の MatchEvaluator に設定するカスタムメソッドをどのように作るかです。
@IT の記事「全角英数字のみを半角に変換するには?」にその例がありますが、そこでは Strings.StrConv メソッドが使われています。
しかしながら、Strings.StrConv メソッドはローケルの違いとか XP 互換モードで期待した結果にならないという問題があるそうです。
数字だけなら辞書を作るのは簡単ですので、Strings.StrConv メソッドを使う代わりに、IEnumerable.Select 拡張メソッドと辞書を使ってカスタムメソッドを実装してみました。
以下にコード例を書きます。その中の Replacer というのが MatchEvaluator に設定するカスタムメソッドです。
Replacer のコードの中で、m.Value はマッチした全角数字の文字列(String 型。IEnumerable<char> を継承している)になります。Select 拡張メソッドは辞書を使って全角数字の文字列の各文字 (Char 型)を半角に置き換え、それを IEnumerable<char> 型のオブジェクトとして返します。
半角数字に置き換えられた IEnumerable<char> 型のオブジェクトを ToArray メソッドで Char[] に変換し、String(Char[]) コンストラクタで半角数字の文字列(String 型)を生成して Replacer メソッドの戻り値として返しています。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace ConsoleApplication
{
class Program
{
// 辞書を作る
public static Dictionary<char, char> dictionary =
new Dictionary<char, char>() {
{'0','0'},{'1','1'},{'2','2'},{'3','3'},
{'4','4'},{'5','5'},{'6','6'},{'7','7'},
{'8','8'},{'9','9'}
};
public static string Convert(string source)
{
Regex regex = new Regex("[0-9]+");
return regex.Replace(source, Replacer);
}
public static String Replacer(Match m)
{
return new String(
m.Value.Select(n => dictionary[n]).ToArray());
}
static void Main(string[] args)
{
String source = "0123456789Ab1C02dEfあい36";
Console.WriteLine(source);
Console.WriteLine(Convert(source));
// Regex を使わなくても以下のようにして可能
String replaced = new String(
source.Select(
n => (dictionary.ContainsKey(n) ? dictionary[n] : n)
).ToArray()
);
Console.WriteLine(replaced);
/* 結果は:
0123456789Ab1C02dEfあい36
0123456789Ab1C02dEfあい36
0123456789Ab1C02dEfあい36
*/
}
}
}