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

double.Parse("3.5") 

收益率为35和

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

抛出一个FormatException。

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

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


当前回答

乘以这个数,然后除以之前乘以的数。

例如,

perc = double.Parse("3.555)*1000;
result = perc/1000

其他回答

我对这个话题的看法,试图提供一个通用的,双重转换方法:

private static double ParseDouble(object value)
{
    double result;

    string doubleAsString = value.ToString();
    IEnumerable<char> doubleAsCharList = doubleAsString.ToList();

    if (doubleAsCharList.Where(ch => ch == '.' || ch == ',').Count() <= 1)
    {
        double.TryParse(doubleAsString.Replace(',', '.'),
            System.Globalization.NumberStyles.Any,
            CultureInfo.InvariantCulture,
            out result);
    }
    else
    {
        if (doubleAsCharList.Where(ch => ch == '.').Count() <= 1
            && doubleAsCharList.Where(ch => ch == ',').Count() > 1)
        {
            double.TryParse(doubleAsString.Replace(",", string.Empty),
                System.Globalization.NumberStyles.Any,
                CultureInfo.InvariantCulture,
                out result);
        }
        else if (doubleAsCharList.Where(ch => ch == ',').Count() <= 1
            && doubleAsCharList.Where(ch => ch == '.').Count() > 1)
        {
            double.TryParse(doubleAsString.Replace(".", string.Empty).Replace(',', '.'),
                System.Globalization.NumberStyles.Any,
                CultureInfo.InvariantCulture,
                out result);
        }
        else
        {
            throw new ParsingException($"Error parsing {doubleAsString} as double, try removing thousand separators (if any)");
        }
    }

    return result;
}

与预期工作:

1.1 1, 1 1000000000 1.000.000.000 1000000000.99 1.000.000.000, 99 5000111.3 5.000.111, 3 0.99, 000111,88 0,99.000. 111.88

没有实现默认转换,因此试图解析1.3、14、1、3.14或类似情况会失败。

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

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);
}

如果没有指定要查找的小数分隔符,这是很困难的,但如果你这样做了,这就是我使用的:

    public static double Parse(string str, char decimalSep)
    {
        string s = GetInvariantParseString(str, decimalSep);
        return double.Parse(s, System.Globalization.CultureInfo.InvariantCulture);
    }

    public static bool TryParse(string str, char decimalSep, out double result)
    {
        // NumberStyles.Float | NumberStyles.AllowThousands got from Reflector
        return double.TryParse(GetInvariantParseString(str, decimalSep), NumberStyles.Float | NumberStyles.AllowThousands, System.Globalization.CultureInfo.InvariantCulture, out result);
    }

    private static string GetInvariantParseString(string str, char decimalSep)
    {
        str = str.Replace(" ", "");

        if (decimalSep != '.')
            str = SwapChar(str, decimalSep, '.');

        return str;
    }
    public static string SwapChar(string value, char from, char to)
    {
        if (value == null)
            throw new ArgumentNullException("value");

        StringBuilder builder = new StringBuilder();

        foreach (var item in value)
        {
            char c = item;
            if (c == from)
                c = to;
            else if (c == to)
                c = from;

            builder.Append(c);
        }
        return builder.ToString();
    }

    private static void ParseTestErr(string p, char p_2)
    {
        double res;
        bool b = TryParse(p, p_2, out res);
        if (b)
            throw new Exception();
    }

    private static void ParseTest(double p, string p_2, char p_3)
    {
        double d = Parse(p_2, p_3);
        if (d != p)
            throw new Exception();
    }

    static void Main(string[] args)
    {
        ParseTest(100100100.100, "100.100.100,100", ',');
        ParseTest(100100100.100, "100,100,100.100", '.');
        ParseTest(100100100100, "100.100.100.100", ',');
        ParseTest(100100100100, "100,100,100,100", '.');
        ParseTestErr("100,100,100,100", ',');
        ParseTestErr("100.100.100.100", '.');
        ParseTest(100100100100, "100 100 100 100.0", '.');
        ParseTest(100100100.100, "100 100 100.100", '.');
        ParseTest(100100100.100, "100 100 100,100", ',');
        ParseTest(100100100100, "100 100 100,100", '.');
        ParseTest(1234567.89, "1.234.567,89", ',');    
        ParseTest(1234567.89, "1 234 567,89", ',');    
        ParseTest(1234567.89, "1 234 567.89",     '.');
        ParseTest(1234567.89, "1,234,567.89",    '.');
        ParseTest(1234567.89, "1234567,89",     ',');
        ParseTest(1234567.89, "1234567.89",  '.');
        ParseTest(123456789, "123456789", '.');
        ParseTest(123456789, "123456789", ',');
        ParseTest(123456789, "123.456.789", ',');
        ParseTest(1234567890, "1.234.567.890", ',');
    }

这对任何文化都适用。它正确地无法解析具有多个小数分隔符的字符串,这与replace而不是swap的实现不同。

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)));

我正在开发一个。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;
   }