Make TryParse compatible with comma or dot decimal separator

帅比萌擦擦* 提交于 2019-12-10 22:03:18

问题


The problem: Let's assume you are using a dot "." as a decimal separator in your regional setting and have coded a string with a comma.

string str = "2,5";

What happens when you decimal.TryParse(str, out somevariable); it?

somevariable will assume 0.

What can you do to solve it?

1- You can

decimal.TryParse(str, NumberStyles.Any, CultureInfo.InvariantCulture, out somevariable);

And it will return 25, and not 2.5 which is wrong.

2- You can

decimal.TryParse(str.Replace(",","."), out num);

And it will return the proper value, BUT, if the user uses "," as a decimal separator it will not work.

Possible solution that I can't make it work:

Get the user decimal separator in regional settings:

char sepdec = Convert.ToChar(CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator);

And make somehow the replace from ",",sepdec , that way it would stay a comma if its a comma, and replace by an actual dot if the user uses dots.

Hints?

Edit: Many users posted useful information, lately, using the arguments NumberStyles.Any, CultureInfo.GetCultureInfo("pt-PT") on a tryParse wouldn't work if your separator is set to "," So it pretty much doesnt fullfill the premise of making a tryparse "universal".

I'll work around this, if anyone has more hints you'r welcome


回答1:


I know the thread is a little bit older, but I try to provide an answer.

I use regular expression to determine the used number format in the string. The regex also matches numbers without decimal separators ("12345").

var numberString = "1,234.56"; // en
// var numberString = "1.234,56"; // de
var cultureInfo = CultureInfo.InvariantCulture;
// if the first regex matches, the number string is in us culture
if (Regex.IsMatch(numberString, @"^(:?[\d,]+\.)*\d+$"))
{
    cultureInfo = new CultureInfo("en-US");
}
// if the second regex matches, the number string is in de culture
else if (Regex.IsMatch(numberString, @"^(:?[\d.]+,)*\d+$"))
{
    cultureInfo = new CultureInfo("de-DE");
}
NumberStyles styles = NumberStyles.Number;
bool isDouble = double.TryParse(numberString, styles, cultureInfo, out number);

HTH

Thomas




回答2:


Instead of checking the culture or replace, it's possible to use TryParse and supporting both separators without too much code.

double d;
if (double.TryParse("12.3", System.Globalization.NumberStyles.Any, CultureInfo.InvariantCulture, out d))
    Console.WriteLine("Value converted {0}", d);
else
    Console.WriteLine("Unable to parse this number");



回答3:


I found a solution, I'm a beginner on this regional and comma-dots theme so if you have comments to improve the understanding of this please be welcome.

We start of by getting what decimal separator the user has set in his regional options outside before the Form{InitializeComponent();} (I want a universal variable that will allow me to correct the code)

 char sepdec = Convert.ToChar(CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator);

In the tryParse, to get it to behave universally we will read the dots and commas in the string, and turn them into the decimal separator we defined as sepdec

decimal.TryParse(str.Replace(",",sepdec.ToString()).Replace(".",sepdec.ToString()),  out somevariable);

I hope this helps, please comment improvement suggestions!



来源:https://stackoverflow.com/questions/29452263/make-tryparse-compatible-with-comma-or-dot-decimal-separator

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!