C# 用逗号和点解析字符串以加倍

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11560465/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 18:18:56  来源:igfitidea点击:

Parse strings to double with comma and point

c#

提问by metacircle

I am trying to write a function which basically converts an array of strings to an array of strings where all the doubles in the array are rounded to the number of decimalplaces i set. There can also be strings in the array which are no double values at all.

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

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

The result has to be: "hello" , "0.12", "0.12" but it is "hello", "123.00", "0.12" will treat the comma in the wrong way. Does anyone have a simple and efficient solution for this?

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

采纳答案by mmdemirbas

You want to treat dot (.) like comma (,). So, replace

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

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

with

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

回答by Paul Fleming

Use this overload of double.TryParse to specify allowed formats:

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

Double.TryParse Method (String, NumberStyles, IFormatProvider, Double%)

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

By default, double.TryParse will parse based on current culture specific formats.

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

回答by Daniel A.A. Pelsmaeker

The problem is that you (or the system) cannot distinguish a decimal separator from a thousands separator when they can be both a comma or dot. For example:

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

In my culture,

1.123is a normal notation for a number above 1000; whereas

1,123is a number near 1.

在我的文化中,

1.123是大于 1000 的数字的正常表示法;然而

1,123是一个接近 1 的数字。

Using the invariant culture defaults to using the dot as a decimal separator. In general you should ensure that all numbers are written using the same constant culture on all systems (e.g. the invariant culture).

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

If you are sure that your numbers never contain anything other than a comma or dot for a decimal separator (i.e. no thousands separators), I'd String.Replace()the comma with a dot and do the rest as you did.

如果您确定您的数字除了逗号或小数点分隔符(即没有千位分隔符)之外从不包含任何其他内容,我会String.Replace()用一个点号逗号,然后像您一样做其余的事情。

Otherwise, you'll have a hard time programming something that can distinguish 1.123from 1,123without knowing the culture.

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

回答by Axxelsian

You can check if the string contains a decimal point using

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

string s="";

string s="";

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

and then treat that as a decimal, otherwise just pass the non-double value along.

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

回答by hultqvist

To treat both , and . as decimal point you must not only replace one with the other, but also make sure the Culture used parsing interprets it as a decimal point.

对待 , 和 。作为小数点,您不仅必须将一个替换为另一个,还必须确保使用的文化解析将其解释为小数点。

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

回答by OliverAssad

You DO NOT NEED to replace the comma and dot..

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

I have had the very same problem. The reason is simple, the conversion culture plays a big role in which the comma or a dot is interpreted. I use a German culture where the comma distinguish the fractions, where as elsewhere the dot does the job.

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

Here I made a complete example to make the difference clear.

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

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

The results is the following: enter image description here

结果如下: 在此处输入图片说明

Play around with the culture and you will get the result you need.

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

回答by diegoguevara

try this... it works for me.

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

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

回答by Andrew

Extension to parse decimal number from string.

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

  • No matter number will be on the beginning, in the end, or in the middle of a string.
  • No matter if there will be only number or lot of "garbage" letters.
  • No matter what is delimiter configured in the cultural settings on the PC: it will parse dot and comma both correctly.
  • Ability to set decimal symbol manually.

    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;
        }
    }
    
  • 无论数字是在字符串的开头、结尾还是中间。
  • 无论是只有数字还是大量的“垃圾”字母。
  • 无论在 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;
        }
    }
    

How to use:

如何使用:

"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

回答by Sinipelto

Make two static cultures, one for comma and one for point.

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

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

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

Then use each one respectively, depending on the input (using a function):

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

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

Then loop through your arrays

然后遍历你的数组

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

This should work even though the host environment and culture changes.

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