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”,即“.”))如果您的currentCulture.NumberCIMALSEperator是一个“,”,则返回445。是的,您是对的。需要更新代码。也许以后你们会在这两种文化中测试这一点,正如hultqvist所指出的
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);