我想把“3.5”这样的字符串解析为double。然而,

double.Parse("3.5") 

收益率为35和

double.Parse("3.5", System.Globalization.NumberStyles.AllowDecimalPoint) 

抛出一个FormatException。

现在我的计算机的区域设置为德语,其中逗号用作小数分隔符。它可能需要做一些事情,double.Parse()期望“3,5”作为输入,但我不确定。

如何解析包含十进制数字的字符串,该十进制数字可能是或可能不是我当前地区指定的格式?


当前回答

我正在开发一个。net Maui应用程序,可以在Windows、Mac、Android和iPhone上运行。我有3个双精度值,我解析和存储使用'。(如。“32.5”)在所有情况下:纬度、经度和海拔。我碰巧将Android和iPhone设置为西班牙语,并注意到Android会解析'。字符串很好。但是,iPhone拒绝正确解析它,除非我用','代替'.'。否则,结果总是一个巨大的数字。

我没有处理复杂的本地化问题,而是提出了一个简单的解决方案,即利用双数字的特定限制。

                     case "Lat":
                        waypoint.Lat = ParseDouble(xmlVal, 90);
                        break;
                     case "Lon":
                        waypoint.Lon = ParseDouble(xmlVal, 180);
                        break;
                     case "Alt":
                        waypoint.Alt = ParseDouble(xmlVal, 32000);

   public static double ParseDouble(string val, double limit)
   {
      double result;
      if (double.TryParse(val, out result))
      {
         if (Math.Abs(result) <= limit)
            return result;
         else if (double.TryParse(val.Replace('.', ','), out result))
         {
            if (Math.Abs(result) <= limit)
               return result;
         }
      }
      return 0;
   }

其他回答

下面的代码在任何场景下都可以完成这项工作。这是一点解析。

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);
}
double.Parse("3.5", CultureInfo.InvariantCulture)

我不能写评论,所以我在这里写:

double.Parse("3.5", CultureInfo.InvariantCulture)不是一个好主意,因为在加拿大我们写3,5而不是3.5,这个函数的结果是35。

我在自己的电脑上进行了测试:

double.Parse("3.5", CultureInfo.InvariantCulture) --> 3.5 OK
double.Parse("3,5", CultureInfo.InvariantCulture) --> 35 not OK

这是Pierre-Alain Vigeant提到的正确方法

public static double GetDouble(string value, double defaultValue)
{
    double result;

    // Try parsing in the current culture
    if (!double.TryParse(value, System.Globalization.NumberStyles.Any, CultureInfo.CurrentCulture, out result) &&
        // Then try in US english
        !double.TryParse(value, System.Globalization.NumberStyles.Any, CultureInfo.GetCultureInfo("en-US"), out result) &&
        // Then in neutral language
        !double.TryParse(value, System.Globalization.NumberStyles.Any, CultureInfo.InvariantCulture, out result))
    {
        result = defaultValue;
    }
    return result;
}

而不是必须在所有解析中指定一个语言环境,我更喜欢设置一个应用程序范围内的语言环境,尽管如果字符串格式在应用程序中不一致,这可能不起作用。

CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("pt-PT");
CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo("pt-PT");

在应用程序的开始定义它将使所有双解析都期望逗号作为小数分隔符。您可以设置适当的区域设置,以便十进制和千位分隔符适合您正在解析的字符串。

string testString1 = "2,457";
string testString2 = "2.457";    
double testNum = 0.5;
char decimalSepparator;
decimalSepparator = testNum.ToString()[1];

Console.WriteLine(double.Parse(testString1.Replace('.', decimalSepparator).Replace(',', decimalSepparator)));
Console.WriteLine(double.Parse(testString2.Replace('.', decimalSepparator).Replace(',', decimalSepparator)));