如何将带小数的数字的外部字符串表示转换为双精度?

时间:2010-08-20 20:47:24

标签: c# .net parsing

我正在实习,在那里对从XML文件读取的字符串进行解析。具体而言,字符串是十进制数的表示。当我尝试解析格式不同于具有逗号分隔符和小数点的十进制字符串时出现问题。例如,各国以不同方式格式化十进制数字的方式:

  • 法国:1 234 567,89 == 1,234,567.89
  • 德国:1.234.567,89 == 1,234,567.89
  • 澳大利亚:1 234 567.89 == 1,234,567,89

我很确定这些国家/地区如何代表十进制数字。如果没有抱歉。点数为1,234,567.89可以用很多方式表示。

我想要做的是确保我尝试解析它的十进制数的字符串表示应该是1,234,567.89。

我认为解决这个问题的一个好方法是使用double.TryParse()方法,但我无法让它工作。

以下是我在一个小测试应用程序中得到的结果:

double num;
Console.WriteLine(double.TryParse("1 234 567,89", NumberStyles.Any, CultureInfo.InvariantCulture.NumberFormat, out num).ToString());
Console.WriteLine(num.ToString());
Console.WriteLine(double.TryParse("1.234.567,89", NumberStyles.Any, CultureInfo.InvariantCulture.NumberFormat, out num).ToString());
Console.WriteLine(num.ToString());
Console.WriteLine(double.TryParse("1 234 567.89", NumberStyles.Any, CultureInfo.InvariantCulture.NumberFormat, out num).ToString());
Console.WriteLine(num.ToString());

我所做的只是查看TryParse是否有效,然后打印该号码。在这种情况下,TryParse总是输出false。 false表示TryParse捕获了FormatException,显然无法将字符串转换为double。

这看起来是正确还是我对我正在做的事情完全感到困惑?

我的印象是,通过说NumberStyles.Any,它表示该字符串可以是任何形式的十进制数。我也认为CultureInfo.InvariantCulture.NumberFormat会返回文化上独立的数字格式信息。换句话说,它将创建1,234,567.89形式的小数。

感谢您抽出宝贵时间阅读我的问题。任何帮助将不胜感激。

4 个答案:

答案 0 :(得分:2)

不同的文化有不同的千位分隔符,十进制分隔符等等,因此您需要使用适当的CultureInfo来进行文化。

您正在使用InvariantCulture - 它根本不代表任何文化,默认情况下,特定的数字分隔符与en-US的分隔符相同。

例如,如果要解析法语格式的数字,请从MSDN(略微修改)中获取示例:

double number;
string value = "1345,978";
NumberStyle style = NumberStyles.AllowDecimalPoint;
CultureInfo culture = CultureInfo.CreateSpecificCulture("fr-FR");
if (Double.TryParse(value, style, culture, out number))
   Console.WriteLine("Converted '{0}' to {1}.", value, number);
  

显示器:

     

将'1345,978'转换为1345.978。

答案 1 :(得分:1)

这可以在任何情况下完成工作。它有点解析。

List<string> inputs = new List<string>()
{
    "1.234.567,89",
    "1 234 567,89",
    "1 234 567.89",
    "1,234,567.89",
    "123456789",
    "1234567,89",
    "1234567.89",
};
string output;

foreach (string input in inputs)
{
    // unify string (no spaces, only . )
    output = input.Trim().Replace(" ", "").Replace(",", ".");

    // split it on points
    string[] split = output.Split('.');

    if (split.Count() > 1)
    {
        // take all parts except last
        output = string.Join("", split.Take(split.Count()-1).ToArray());

        // combine token parts with last part
        output = string.Format("{0}.{1}", output, split.Last());
    }

    // parse double invariant
    double d = double.Parse(output, CultureInfo.InvariantCulture);
    Console.WriteLine(d);
}

答案 2 :(得分:0)

如果你总是保证有1,234,567.00美分,你可以忽略所有的标点符号

答案 3 :(得分:0)

我建议大家都同意CultureInfo.InvariantCulture.NumberFormat。您可以尝试一些可以自动验证的正式规范,如XSD。