将包含小数的字符串规范化为特定的CultureInfo.NumberFormat

时间:2017-11-07 23:14:49

标签: c# .net parsing decimal cultureinfo

我正在努力将数字规范化为特定的CultureInfo,并应用其NumberFormat

假设我有一个字符串,其中也包含一些字符,所以我需要清理它:

var cleanedInput = Regex.Replace(userInput, @"[^0-9-,'.]+", "");

所以我基本上保持, '.。我这样做是因为取决于CultureInfo,.用于分隔小数或分组数字。

考虑到这一点,我应用Decimal.TryParse方法,指定NumberStyle以允许小数,IFormatProvider将被动态地应用于所需的“本地”{{1 }}

CultureInfo.NumberFormat

假设我们输入decimal numericData; if (!decimal.TryParse(cleanedInput, NumberStyles.AllowDecimalPoint, LocaleUser.NumberFormat, out numericData)) throw new Exception($"Error occurred. Could not parse:{cleanedInput} "); 。清理完毕后,我们会获得"hi9000,99hi"。尼斯。 然后,我们应用"9000,99"并返回TryParse Decimal。重要的是说我实际上正在使用9000.99 es-ES作为小数点分隔符CultureInfo。我基本上期待,9000,99

代码没有引发9.000,99,但看起来它没有应用我指定的Exception

我到底缺少什么?我觉得CultureInfo是一把瑞士军刀,我处理得很好。

非常感谢提前。

2 个答案:

答案 0 :(得分:0)

使用double.Parse,decimal.Parse或decimal.TryParse似乎有效。 CultureInfo是如何定义的?

string value = "9000,99";
decimal number;
CultureInfo culture = CultureInfo.CreateSpecificCulture("es-ES");

try {
    number = decimal.Parse(value, culture);
    decimal.TryParse(value, NumberStyles.Any, culture, out decimal num);
    Console.WriteLine($"{culture.Name}: {value} = {number} / {num}");                       
} catch (FormatException) {
    Console.WriteLine($"{culture.Name}: Unable to parse [{value}]");
}

输出:

es-ES: 9000,99 = 9000.99 / 9000.99

答案 1 :(得分:0)

所以,假设一个Decimal总是一个Decimal并且没有格式,就像在评论中所说的那样,我错误地关注了问题以及我在寻找什么!

我终于使用了这种方法:

private decimal CleanUserInput(string userInput, CultureInfo localeUser)
{
    if (localeUser == null)
        throw new Exception("A CultureInfo must be specified. ");

    var cleanedInput = Regex.Replace(userInput, @"[^0-9-,\.']+", "");
    if (string.IsNullOrWhiteSpace(cleanedInput))
        throw new Exception("Data provided has no numbers to be parsed. ");

    decimal numericData;
    if (!decimal.TryParse(cleanedInput, NumberStyles.Any, localeUser, out numericData))
        throw new Exception($"Couldn't parse {cleanedInput} . Make sure the applied CultureInfo ({LocaleUser.DisplayName}) is the correct one. Decimal separator to be applied: <{LocaleUser.NumberFormat.NumberDecimalSeparator}> Numeric group separator to be applied: <{LocaleUser.NumberFormat.NumberGroupSeparator}>");

    return numericData;
}