避免使用decimal.TryParse识别" 1.1.1"或" 1,1,1"作为小数

时间:2016-03-07 09:27:40

标签: c# type-conversion number-formatting tryparse

我在字符串识别方面存在问题:我尝试仅以正确的格式识别数字,但不知道如何识别。

我正在写一种文化不变的方式,所以我需要认识到","和"。"作为十进制和千位分隔符,反之亦然。

所有这些对我来说都是正确的格式:

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

this is the fiddle to test it

但" 1,1,1" " 1.1.1"被读作有效数字。不是。

如果我使用我的特定文化(" it-IT")," 1,1,1"被认可并且" 1.1.1"不是。

如何丢弃所有无效字符串?

2 个答案:

答案 0 :(得分:0)

我最后用个人解析器,我希望找到一个更好的解决方案,但阅读评论似乎很不可能

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 formatand,然后尝试转换它

最后一次测试是看到没有与“数字”相似的文字,因为像“001”,“100 01”这样的字符串不是数字。

比率是:每个字符串必须保持不变:转换为数字的“001”变为“1”,与原始值不同,因此必须避免此转换

this is the fiddle

答案 1 :(得分:0)

我建议您使用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