Char.IsNumber/GetNumericValue
【VB.NET】指定した文字が数字かどうか判定する(IsDigit, IsNumber, IsNumeric)を見ていて、Char.GetNumericValueとint.Parse/TryParseに違いがあるのかどうかが気になったので試してみた。
using System; class NumericTest { public static void Main() { Console.OutputEncoding = System.Text.Encoding.UTF8; Char[] num = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '鄯', '鄱', '鄴', '?', '?', '?', '?', '?', '㈠', '㈡', '㈩', '⑴', '⒇', '❶', '❿', '➀', '➉', '㊀', '㊁', '㊉', '⒈', '⒛', '➊', '➓', '¹', '⁹', '₁', '₉', '〇', '一', '九', '零', '壱', '弐', '玖'}; foreach (Char c in num) { int v; if (!int.TryParse(c.ToString(), out v)) v = -1; Console.WriteLine( "{0}\tIsDigit:{1}\tIsNumber:{2}\tGetNumericValue:{3}\tParse:{4}", c, Char.IsDigit(c), Char.IsNumber(c), Char.GetNumericValue(c), v); } } }
はてながUnicode対応じゃないせいで、見にくいことになってるけど、本当は、
結論から言うと、おそらく、Char.IsDigitがtrueな場合には、int.Parseも動く。一方で、Char.IsNumberがtrueでも、int.Parseできるとは限らないが、Char.GetNumericValueは数値の値を返してくれるようだ。
ただ、じゃぁ、数値解析ルーチンは、Char.GetNumericValueを使えば良いかといえば、こいつは、漢数字とかローマ数字まで相手にしてしまうので、状況に応じて判断するしかないだろう。
全角の数字文字列を処理したいだけだったら、NFKD・NFKCあたりで正規化してからint.Parseするのが良いかも。
と思ったけど、やっぱり、Char.IsDigitでチェックして、int.Parseというのには問題があるようだ。
http://blogs.msdn.com/b/oldnewthing/archive/2004/03/09/86555.aspx
結局、
static bool isDigit(Char c) { return c >= '0' && c <= '9'; }
なんていうベタなのが順当らしい・・・。