避免 decimal.TryParse 将“1.1.1”或“1,1,1”识别为十进制
Avoid decimal.TryParse to recognize "1.1.1" or "1,1,1" as decimal
我在字符串识别方面遇到了问题:我试图只识别格式正确的数字,但找不到方法。
我正在编写文化不变的方式,所以我需要识别“,”和“。”作为小数点和千位分隔符,反之亦然。
所有这些对我来说都是正确的格式:
12,1
12.1
1.000,12
1,000.12
但是这样的事情是错误的
1.2.3
1,2,3
我试过了:
NumberStyles style;
decimal n;
object valore;
style = NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign | NumberStyles.AllowThousands;
Console.WriteLine(decimal.TryParse(valore.ToString(), style , CultureInfo.InvariantCulture, out n));
但是“1,1,1”被读取为有效数字,而“1.1.1”不是。
如果我使用我的特定区域性 ("it-IT"),“1,1,1”会被识别,而“1.1.1”不会。
如何丢弃所有无效字符串?
我用个人解析器结束了这个,我希望找到更好的解决方案,但阅读评论似乎是不可能的
public static bool tryValoreNumerico(object valore, out decimal valoreRestituito)
{
decimal n;
string testoNormalizzato;
valoreRestituito = 0;
// normalizzazione
if (valore.ToString().Contains(",") && valore.ToString().Contains("."))
{
if (valore.ToString().IndexOf(".") < valore.ToString().IndexOf(","))
{
testoNormalizzato = valore.ToString().Replace(".", "");
}
else
{
testoNormalizzato = valore.ToString().Replace(",", "");
}
}
else
{
if ((valore.ToString().Length - valore.ToString().Replace(",", "").Length) > 1)
{
string[] pezzi = valore.ToString().Split(',');
for (int i = 1; i < pezzi.Length; i++ )
{
if (pezzi[i].Length != 3)
return false;
}
testoNormalizzato = valore.ToString().Replace(",", "");
}
else if ((valore.ToString().Length - valore.ToString().Replace(".", "").Length) > 1)
{
string[] pezzi = valore.ToString().Split('.');
for (int i = 1; i < pezzi.Length; i++)
{
if (pezzi[i].Length != 3)
return false;
}
testoNormalizzato = valore.ToString().Replace(".", "");
}
else
testoNormalizzato = valore.ToString();
}
testoNormalizzato = testoNormalizzato.Replace(",", ".");
if (decimal.TryParse(testoNormalizzato, out n) && testoNormalizzato == Convert.ToDecimal(testoNormalizzato, new CultureInfo("en-US")).ToString().Replace(",", "."))
{
valoreRestituito = Convert.ToDecimal(testoNormalizzato, new CultureInfo("en-US"));
}
return decimal.TryParse(testoNormalizzato, out n) && testoNormalizzato == Convert.ToDecimal(testoNormalizzato, new CultureInfo("en-US")).ToString().Replace(",", ".");
}
简而言之,首先我将数字标准化为 EN 格式,然后尝试将其转换
最后的测试是查看没有文本 "similar" 到数字,因为像“001”、“100 01”这样的字符串不是数字。
比例是:每个字符串必须保持不变:“001”转换为数字变成“1”,与原始值不同,因此必须避免这种转换
我建议您使用 Regex
进行验证,并使用如下自定义解析方法:
public static decimal DecimalParse(string number)
{
if (new Regex(@"^\d+$").IsMatch(number))
{
return decimal.Parse(number, CultureInfo.InvariantCulture);
}
if (new Regex(@"^(\d{0,3}(,\d{3})*(\.\d+)?)$").IsMatch(number))
{
return decimal.Parse(number, CultureInfo.InvariantCulture);
}
return new Regex(@"^(\d{0,3}(\.\d{3})*(,\d+)?)$").IsMatch(number)
? decimal.Parse(number.Replace(".", "").Replace(",", "."), CultureInfo.InvariantCulture)
: 0;
}
结果将是:
string num;
num = "1,000"; Console.WriteLine("{0}", DecimalParse(num)); //1000
num = ",01"; Console.WriteLine("{0}", DecimalParse(num)); //0.01
num = ".02"; Console.WriteLine("{0}", DecimalParse(num)); //0.02
num = "12,1"; Console.WriteLine("{0}", DecimalParse(num)); //12.1
num = "12.1"; Console.WriteLine("{0}", DecimalParse(num)); //12.1
num = "1.000,12"; Console.WriteLine("{0}", DecimalParse(num)); //1000.12
num = "1.000.000,12"; Console.WriteLine("{0}", DecimalParse(num)); //1000000.12
num = "1,000.12"; Console.WriteLine("{0}", DecimalParse(num)); //1000.12
num = "1,000,000.12"; Console.WriteLine("{0}", DecimalParse(num)); //1000000.12
num = "1000"; Console.WriteLine("{0}", DecimalParse(num)); //0
num = "110."; Console.WriteLine("{0}", DecimalParse(num)); //0
num = "110,"; Console.WriteLine("{0}", DecimalParse(num)); //0
num = "1.2.3"; Console.WriteLine("{0}", DecimalParse(num)); //0
num = "1,2,3"; Console.WriteLine("{0}", DecimalParse(num)); //0
我在字符串识别方面遇到了问题:我试图只识别格式正确的数字,但找不到方法。
我正在编写文化不变的方式,所以我需要识别“,”和“。”作为小数点和千位分隔符,反之亦然。
所有这些对我来说都是正确的格式:
12,1
12.1
1.000,12
1,000.12
但是这样的事情是错误的
1.2.3
1,2,3
我试过了:
NumberStyles style;
decimal n;
object valore;
style = NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign | NumberStyles.AllowThousands;
Console.WriteLine(decimal.TryParse(valore.ToString(), style , CultureInfo.InvariantCulture, out n));
但是“1,1,1”被读取为有效数字,而“1.1.1”不是。
如果我使用我的特定区域性 ("it-IT"),“1,1,1”会被识别,而“1.1.1”不会。
如何丢弃所有无效字符串?
我用个人解析器结束了这个,我希望找到更好的解决方案,但阅读评论似乎是不可能的
public static bool tryValoreNumerico(object valore, out decimal valoreRestituito)
{
decimal n;
string testoNormalizzato;
valoreRestituito = 0;
// normalizzazione
if (valore.ToString().Contains(",") && valore.ToString().Contains("."))
{
if (valore.ToString().IndexOf(".") < valore.ToString().IndexOf(","))
{
testoNormalizzato = valore.ToString().Replace(".", "");
}
else
{
testoNormalizzato = valore.ToString().Replace(",", "");
}
}
else
{
if ((valore.ToString().Length - valore.ToString().Replace(",", "").Length) > 1)
{
string[] pezzi = valore.ToString().Split(',');
for (int i = 1; i < pezzi.Length; i++ )
{
if (pezzi[i].Length != 3)
return false;
}
testoNormalizzato = valore.ToString().Replace(",", "");
}
else if ((valore.ToString().Length - valore.ToString().Replace(".", "").Length) > 1)
{
string[] pezzi = valore.ToString().Split('.');
for (int i = 1; i < pezzi.Length; i++)
{
if (pezzi[i].Length != 3)
return false;
}
testoNormalizzato = valore.ToString().Replace(".", "");
}
else
testoNormalizzato = valore.ToString();
}
testoNormalizzato = testoNormalizzato.Replace(",", ".");
if (decimal.TryParse(testoNormalizzato, out n) && testoNormalizzato == Convert.ToDecimal(testoNormalizzato, new CultureInfo("en-US")).ToString().Replace(",", "."))
{
valoreRestituito = Convert.ToDecimal(testoNormalizzato, new CultureInfo("en-US"));
}
return decimal.TryParse(testoNormalizzato, out n) && testoNormalizzato == Convert.ToDecimal(testoNormalizzato, new CultureInfo("en-US")).ToString().Replace(",", ".");
}
简而言之,首先我将数字标准化为 EN 格式,然后尝试将其转换
最后的测试是查看没有文本 "similar" 到数字,因为像“001”、“100 01”这样的字符串不是数字。
比例是:每个字符串必须保持不变:“001”转换为数字变成“1”,与原始值不同,因此必须避免这种转换
我建议您使用 Regex
进行验证,并使用如下自定义解析方法:
public static decimal DecimalParse(string number)
{
if (new Regex(@"^\d+$").IsMatch(number))
{
return decimal.Parse(number, CultureInfo.InvariantCulture);
}
if (new Regex(@"^(\d{0,3}(,\d{3})*(\.\d+)?)$").IsMatch(number))
{
return decimal.Parse(number, CultureInfo.InvariantCulture);
}
return new Regex(@"^(\d{0,3}(\.\d{3})*(,\d+)?)$").IsMatch(number)
? decimal.Parse(number.Replace(".", "").Replace(",", "."), CultureInfo.InvariantCulture)
: 0;
}
结果将是:
string num;
num = "1,000"; Console.WriteLine("{0}", DecimalParse(num)); //1000
num = ",01"; Console.WriteLine("{0}", DecimalParse(num)); //0.01
num = ".02"; Console.WriteLine("{0}", DecimalParse(num)); //0.02
num = "12,1"; Console.WriteLine("{0}", DecimalParse(num)); //12.1
num = "12.1"; Console.WriteLine("{0}", DecimalParse(num)); //12.1
num = "1.000,12"; Console.WriteLine("{0}", DecimalParse(num)); //1000.12
num = "1.000.000,12"; Console.WriteLine("{0}", DecimalParse(num)); //1000000.12
num = "1,000.12"; Console.WriteLine("{0}", DecimalParse(num)); //1000.12
num = "1,000,000.12"; Console.WriteLine("{0}", DecimalParse(num)); //1000000.12
num = "1000"; Console.WriteLine("{0}", DecimalParse(num)); //0
num = "110."; Console.WriteLine("{0}", DecimalParse(num)); //0
num = "110,"; Console.WriteLine("{0}", DecimalParse(num)); //0
num = "1.2.3"; Console.WriteLine("{0}", DecimalParse(num)); //0
num = "1,2,3"; Console.WriteLine("{0}", DecimalParse(num)); //0