C# 使用逗号和点将字符串解析为双精度

C# 使用逗号和点将字符串解析为双精度,c#,C#,我正在尝试编写一个函数,它基本上将一个字符串数组转换为一个字符串数组,数组中的所有双精度都被舍入为我设置的小数位数。数组中也可以有完全没有双精度值的字符串 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" + dec

我正在尝试编写一个函数,它基本上将一个字符串数组转换为一个字符串数组,数组中的所有双精度都被舍入为我设置的小数位数。数组中也可以有完全没有双精度值的字符串

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();
string[,]value=新字符串[1,3];
值[0,0]=“你好”;
值[0,1]=“0.123”;
值[0,2]=“0123”;
整数小数位数=2;
双tmp;
string format=“F”+decimalPlaces.ToString();
IFormatProvider=CultureInfo.InvariantCulture;
for(int i=0;i

结果必须是:“hello”、“0.12”、“0.12”,但它是“hello”、“123.00”、“0.12”将以错误的方式处理逗号。有人对此有简单有效的解决方案吗?

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

默认情况下,double.TryParse将基于当前特定于区域性的格式进行分析。

问题在于,当十进制分隔符和千位分隔符都可以是逗号或点时,您(或系统)无法区分它们。例如:

在我的文化中

1.123
是1000以上数字的正常表示法;鉴于

1123
是一个接近1的数字

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

如果您确定您的数字中除了逗号或小数点分隔符(即,没有千位分隔符)外,没有其他内容,我将
String.Replace()
逗号替换为点,其余的操作与您的操作相同


否则,您将很难编写能够区分
1.123
1123
而不知道区域性的内容。

您可以使用


字符串s=“”

然后将其视为十进制,否则只需传递非双精度值。

要将点(
)视为逗号(
)。那么,替换

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


既要治疗,又要治疗。作为小数点,您不仅必须将一个替换为另一个,还必须确保解析使用的区域性将其解释为小数点

text = text.Replace(',', '.');
return double.TryParse(text, NumberStyles.Any, CultureInfo.InvariantCulture, out value);

不需要替换逗号和点

我也有同样的问题。原因很简单,转换文化在解释逗号或点时起着重要作用。我使用的是一种德国文化,其中逗号区分分数,而在其他地方,点起作用

在这里,我举了一个完整的例子来说明区别

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));
}
结果如下:


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

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

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

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

    不管数字是从一开始,在最后,还是在一个字符串的中间。
  • 不管是只有多少个“垃圾”字母
  • 无论在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

创建两个静态区域性,一个表示逗号,一个表示点

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

    var pointCulture = new CultureInfo("en")
    {
        NumberFormat =
        {
            NumberDecimalSeparator = "."
        }
    };
然后根据输入(使用函数)分别使用每个选项:

然后在数组中循环

    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));
    }
var strings=新列表{“0,12”、“0.122”、“1,23”、“00,0”、“0.00”、“12.5000”、“0.002”、“0001”};
var doubles=新列表();
foreach(字符串中的var值){
double.Add(ConvertToDouble(value));
}
即使宿主环境和区域性发生变化,这也应该有效。

简单使用:

double.Parse("3.5", CultureInfo.InvariantCulture)

另一个选项是使用CultureInfo类中十进制分隔符的信息。知道我们可以在需要时用“.”替换“,”或反之亦然。如果需要使用诸如1000000.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);

同意,对我来说这是最合理的解决方案。您还可以检查字符串是否包含“,”或“.”,但这些解决方案中的任何一个都可以。在所有系统上,“…在所有系统上…”远远超出我的控制范围。您需要在解析时指定区域性,否则它将仅在当前区域性使用“,”作为小数点的情况下工作。对。谢谢你的警告。我知道线程已经死很久了,但是我会用
replace(string,string)
替换
replace(char,char)
以获得更好的性能…替换是个坏主意,因为使用其他区域设置的PC上的应用程序将失败。。。我以后会写更好的补丁。也许你可以解释一下你在做什么。“适合我”不是很有描述性。我在几个具有不同文化背景的电脑上尝试了这个解决方案。它没有按预期工作。我稍后会发布另一个解决方案。我尝试过这个,但它对我不起作用。请查看链接中的图像。CurrentCulture参数在那里是德语。这应该是公认的答案。如果需要更严格的限制,还可以使用
NumberStyles.AllowDecimalPoint
作为第二个参数。这对我很管用!4:45应等于4.75:p对于非winforms应用程序,请使用:var currDecSeparator=Thread.CurrentThread.CurrentCulture.NumberFormat.NumberDecimalSeparator;当使用“.”作为小数符号参数时,这不起作用<代码>Assert.AreEqual(4.45d,DoubleParseAdvanced(“4.45”,即“.”)) 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)); }
double.Parse("3.5", CultureInfo.InvariantCulture)
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);