我经常使用Char.IsDigit
检查char
是否是一个在LINQ查询中特别方便的数字,以便在int.Parse
预先检查"123".All(Char.IsDigit)
。int
。
但是有些字符是数字,但无法像۵
一样解析为// true
bool isDigit = Char.IsDigit('۵');
var cultures = CultureInfo.GetCultures(CultureTypes.SpecificCultures);
int num;
// false
bool isIntForAnyCulture = cultures
.Any(c => int.TryParse('۵'.ToString(), NumberStyles.Any, c, out num));
。
int.Parse
为什么?我的Char.IsDigit
- 通过List<char> digitList = Enumerable.Range(0, UInt16.MaxValue)
.Select(i => Convert.ToChar(i))
.Where(c => Char.IsDigit(c))
.ToList();
预先检查是不正确的吗?
有310个字符是数字:
Char.IsDigit
以下是.NET 4(ILSpy)中public static bool IsDigit(char c)
{
if (char.IsLatin1(c))
{
return c >= '0' && c <= '9';
}
return CharUnicodeInfo.GetUnicodeCategory(c) == UnicodeCategory.DecimalDigitNumber;
}
的实现:
int
那么为什么存在属于DecimalDigitNumber
-category(“十进制数字字符,即0到9范围内的字符......”)的字符,这些字符不能在任何文化中被解析为{{1}}?
答案 0 :(得分:8)
这是因为它正在检查Unicode“Number,Decimal Digit”类别中的所有数字,如下所示:
http://www.fileformat.info/info/unicode/category/Nd/list.htm
这并不意味着它是当前语言环境中的有效数字字符。事实上,使用int.Parse()
,您只能解析正常的英文数字,无论语言环境设置如何。
例如,不工作:
int test = int.Parse("٣", CultureInfo.GetCultureInfo("ar"));
即使٣
是有效的阿拉伯数字字符,“ar”也是阿拉伯语区域设置标识符。
Microsoft文章"How to: Parse Unicode Digits"声明:
.NET Framework解析为十进制的唯一Unicode数字是ASCII数字0到9,由代码值U + 0030到U + 0039指定。 .NET Framework将所有其他Unicode数字解析为字符。
但请注意,您可以使用char.GetNumericValue()
将unicode数字字符转换为数字等效字符作为double。
返回值是double而不是int的原因是因为这样的事情:
Console.WriteLine(char.GetNumericValue('¼')); // Prints 0.25
您可以使用类似的内容将字符串中的所有数字字符转换为ASCII等效字符:
public string ConvertNumericChars(string input)
{
StringBuilder output = new StringBuilder();
foreach (char ch in input)
{
if (char.IsDigit(ch))
{
double value = char.GetNumericValue(ch);
if ((value >= 0) && (value <= 9) && (value == (int)value))
{
output.Append((char)('0'+(int)value));
continue;
}
}
output.Append(ch);
}
return output.ToString();
}
答案 1 :(得分:3)