Tim*_*ter 9 .net c# string int character-encoding
我经常Char.IsDigit用来检查a 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));
Run Code Online (Sandbox Code Playgroud)
这是为什么?我的int.Parse-precheck Char.IsDigit因此不正确吗?
有310个字符是数字:
List<char> digitList = Enumerable.Range(0, UInt16.MaxValue)
.Select(i => Convert.ToChar(i))
.Where(c => Char.IsDigit(c))
.ToList();
Run Code Online (Sandbox Code Playgroud)
这是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;
}
Run Code Online (Sandbox Code Playgroud)
那么为什么有属于DecimalDigitNumber-category的字符("十进制数字字符,即0到9之间的字符......")无法int在任何文化中解析?
这是因为它正在检查Unicode"Number,Decimal Digit"类别中的所有数字,如下所示:
http://www.fileformat.info/info/unicode/category/Nd/list.htm
这并不意味着它是当前语言环境中的有效数字字符.实际上int.Parse(),无论语言环境设置如何,您都可以只解析正常的英文数字.
例如,这不起作用:
int test = int.Parse("?", CultureInfo.GetCultureInfo("ar"));
Run Code Online (Sandbox Code Playgroud)
即使?是有效的阿拉伯数字字符,"ar"也是阿拉伯语区域设置标识符.
微软文章"如何:解析Unicode数字"指出:
.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
Run Code Online (Sandbox Code Playgroud)
您可以使用类似的东西将字符串中的所有数字字符转换为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();
}
Run Code Online (Sandbox Code Playgroud)