82

我正在尝试编写一个函数,该函数基本上将字符串数组转换为字符串数组,其中数组中的所有双精度数都舍入到我设置的小数位数。数组中也可以有根本不是双精度值的字符串。

string[,] values = new string[1, 3];

values[0, 0] = "hello";
values[0, 1] = "0.123";
values[0, 2] = "0,123";

int decimalPlaces = 2;

double tmp;
string format = "F" + decimalPlaces.ToString();
IFormatProvider provider = CultureInfo.InvariantCulture;
for (int i = 0; i < values.GetLength(0); i++)
{
    for (int j = 0; j < values.GetLength(1); j++)
    {
        if (double.TryParse(values[i, j], out tmp))
        {
            values[i, j] = tmp.ToString(format, provider);
        }
    }
}

Console.ReadLine();

结果必须是: "hello" , "0.12", "0.12" 但它是 "hello", "123.00", "0.12" 会以错误的方式处理逗号。有没有人对此有一个简单有效的解决方案?

4

13 回答 13

170

同时处理 , 和 。作为小数点,您不仅必须用另一个替换一个,而且还要确保使用的文化解析将其解释为小数点。

text = text.Replace(',', '.');
return double.TryParse(text, NumberStyles.Any, CultureInfo.InvariantCulture, out value);
于 2013-10-30T09:38:34.920 回答
52

您不需要替换逗号和点..

我遇到了同样的问题。原因很简单,转换文化在解释逗号或点时起着很大的作用。我使用德国文化,其中逗号区分分数,而在其他地方,点就可以了。

这里我做了一个完整的例子来说明区别。

string[] doubleStrings = {"hello", "0.123", "0,123"};
double localCultreResult;
foreach (var doubleString in doubleStrings)
{
    double.TryParse(doubleString, NumberStyles.Any, CultureInfo.CurrentCulture, out localCultreResult);
    Console.WriteLine(string.Format("Local culture results for the parsing of {0} is {1}", doubleString, localCultreResult));
}

double invariantCultureResult;
foreach (var doubleString in doubleStrings)
{
    double.TryParse(doubleString, NumberStyles.Any, CultureInfo.InvariantCulture, out invariantCultureResult);
    Console.WriteLine(string.Format("Invariant culture results for the parsing of {0} is {1}", doubleString, invariantCultureResult));
}

结果如下: 在此处输入图像描述

玩弄文化,你会得到你需要的结果。

于 2015-02-24T09:32:45.030 回答
29

您希望将点 ( .) 视为逗号 ( ,)。所以,更换

if (double.TryParse(values[i, j], out tmp))

if (double.TryParse(values[i, j].Replace('.', ','), out tmp))
于 2012-07-19T12:13:01.910 回答
19

问题是您(或系统)无法区分小数分隔符和千位分隔符,因为它们可以是逗号或点。例如:

在我的文化中,

1.123是 1000 以上数字的正常表示法;然而

1,123是接近 1 的数字。

使用不变区域性默认使用点作为小数分隔符。一般来说,您应该确保在所有系统上使用相同的常量文化(例如,不变文化)编写所有数字。

如果您确定您的数字从不包含逗号或小数点分隔符(即没有千位分隔符)以外的任何内容,那么我会String.Replace()使用带点的逗号,然后像您一样执行其余操作。

否则,您将很难在不了解文化的情况下编写可以区分1.123的东西。1,123

于 2012-07-19T12:06:24.737 回答
5

制作两种静态文化,一种用于逗号,一种用于点。

    var commaCulture = new CultureInfo("en")
    {
        NumberFormat =
        {
            NumberDecimalSeparator = ","
        }
    };

    var pointCulture = new CultureInfo("en")
    {
        NumberFormat =
        {
            NumberDecimalSeparator = "."
        }
    };

然后根据输入(使用函数)分别使用每一个:

    public double ConvertToDouble(string input)
    {
        input = input.Trim();

        if (input == "0") {
            return 0;
        }

        if (input.Contains(",") && input.Split(',').Length == 2)
        {
            return Convert.ToDouble(input, commaCulture);
        }

        if (input.Contains(".") && input.Split('.').Length == 2)
        {
            return Convert.ToDouble(input, pointCulture);
        }

        throw new Exception("Invalid input!");
    }

然后遍历你的数组

    var strings = new List<string> {"0,12", "0.122", "1,23", "00,0", "0.00", "12.5000", "0.002", "0,001"};
    var doubles = new List<double>();

    foreach (var value in strings) {
        doubles.Add(ConvertToDouble(value));
    }

即使宿主环境和文化发生变化,这也应该有效。

于 2019-02-05T17:30:53.233 回答
3

简单使用:

double.Parse("3.5", CultureInfo.InvariantCulture)
于 2021-03-30T10:00:28.833 回答
1

使用这个 double.TryParse 的重载来指定允许的格式:

Double.TryParse 方法(字符串、NumberStyles、IFormatProvider、Double%)

默认情况下,double.TryParse 将根据当前的文化特定格式进行解析。

于 2012-07-19T12:06:11.287 回答
1

从字符串解析十进制数的扩展。

  • 无论数字是在字符串的开头、结尾还是中间。
  • 无论是否只有数量或大量的“垃圾”字母。
  • 无论在 PC 的文化设置中配置什么分隔符:它都会正确解析点和逗号。
  • 能够手动设置十进制符号。

    public static class StringExtension
    {
        public static double DoubleParseAdvanced(this string strToParse, char decimalSymbol = ',')
        {
            string tmp = Regex.Match(strToParse, @"([-]?[0-9]+)([\s])?([0-9]+)?[." + decimalSymbol + "]?([0-9 ]+)?([0-9]+)?").Value;
    
            if (tmp.Length > 0 && strToParse.Contains(tmp))
            {
                var currDecSeparator = System.Windows.Forms.Application.CurrentCulture.NumberFormat.NumberDecimalSeparator;
    
                tmp = tmp.Replace(".", currDecSeparator).Replace(decimalSymbol.ToString(), currDecSeparator);
    
                return double.Parse(tmp);
            }
    
            return 0;
        }
    }
    

如何使用:

"It's 4.45 O'clock now".DoubleParseAdvanced(); // will return 4.45
"It's 4,45 O'clock now".DoubleParseAdvanced(); // will return 4.45
"It's 4:45 O'clock now".DoubleParseAdvanced(':'); // will return 4.45
于 2016-11-08T03:23:28.163 回答
0

您可以使用检查字符串是否包含小数点

string s="";

        if (s.Contains(','))
        { 
        //treat as double how you wish
        }

然后将其视为小数,否则只需传递非双精度值。

于 2012-07-19T12:09:11.957 回答
0

如果我想解析一个带小数点分隔符的数字,我将使用以下代码段:

public bool TryParseDecimal(string value, out decimal result) {
    const string your_separator = ",";

    var numberFormat = new NumberFormatInfo {
            NumberDecimalSeparator = your_separator
    };

    return decimal.TryParse(value, NumberStyles.AllowDecimalPoint, numberFormat, out result);
}

我不认为使用文化或字符串操作表达了用非“。”转换数字的意图。小数点。

于 2021-07-08T07:34:48.450 回答
0

对我来说,使用文化信息不是一种选择,因为该应用程序在具有不同文化的系统上运行,但输入字符串要在未知文化的位置进行解析。

所以我提到规范化字符串表示,然后使用 CultureInfo.InvariantCulture 对其进行转换:

    private static double NormalizeAndParse(string strDouble)
    {
        string strDoubleNormalized;

        if (strDouble.Contains(","))
        {
            var strReplaced = strDouble.Replace(",", ".");
            var decimalSeparatorPos = strReplaced.LastIndexOf('.');
            var strInteger = strReplaced.Substring(0, decimalSeparatorPos);
            var strFractional = strReplaced.Substring(decimalSeparatorPos);

            strInteger = strInteger.Replace(".", string.Empty);
            strDoubleNormalized = strInteger + strFractional;
        }
        else
        {
            strDoubleNormalized = strDouble;
        }

        return Double.Parse(strDoubleNormalized, NumberStyles.Any, CultureInfo.InvariantCulture);
    }
于 2022-03-03T10:41:15.037 回答
0

另一种选择是使用 CultureInfo 类中小数点分隔符的信息。知道我们可以用“。”替换“,”。需要时反之亦然。如果需要对 1,000,000.23 之类的数字进行处理,则此类中还提供了数字分组符号。

string decimalSeparator = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;
        string value = "";

        if (decimalSeparator == ".")
        {
            value = rateLimitTextBox.Text.Replace(",", ".");
        }
        else if (decimalSeparator == ",")
        {
            value = rateLimitTextBox.Text.Replace(".", ",");
        }

        bool LimitAcceptable = decimal.TryParse(value, NumberStyles.Any, CultureInfo.CurrentCulture, out decimal limit);
于 2021-03-31T22:05:48.583 回答
-1

试试这个……它对我有用。

double vdouble = 0;
string sparam = "2,1";

if ( !Double.TryParse( sparam, NumberStyles.Float, CultureInfo.InvariantCulture, out vdouble ) )
{
    if ( sparam.IndexOf( '.' ) != -1 )
    {
        sparam = sparam.Replace( '.', ',' );
    }
    else
    {
        sparam = sparam.Replace( ',', '.' );
    }

    if ( !Double.TryParse( sparam, NumberStyles.Float, CultureInfo.InvariantCulture, out vdouble ) )
    {
        vdouble = 0;
    }
}
于 2015-05-27T15:27:07.213 回答