【问题标题】:Unable to restrict number of decimal digits when parsing a string to decimal in C#在 C# 中将字符串解析为十进制时无法限制小数位数
【发布时间】:2023-04-01 12:57:01
【问题描述】:

我正在尝试将字符串解析为小数,如果字符串中的小数点后有 2 位以上的数字,则解析应该失败。

例如:

1.25 有效,但1.256 无效。

我尝试使用C#中的decimal.TryParse方法以如下方式解决,但这无济于事...

NumberFormatInfo nfi = new NumberFormatInfo();
nfi.NumberDecimalDigits = 2;
if (!decimal.TryParse(test, NumberStyles.AllowDecimalPoint, nfi, out s))
{
    Console.WriteLine("Failed!");
    return;
}            
Console.WriteLine("Passed");

有什么建议吗?

【问题讨论】:

    标签: c# .net parsing decimal


    【解决方案1】:

    看看Regex。有各种各样的主题涵盖了这个主题。

    示例: Regex to match 2 digits, optional decimal, two digits

    Regex decimalMatch = new Regex(@"[0-9]?[0-9]?(\.[0-9]?[0-9]$)"); 这应该适合你的情况。

       var res = decimalMatch.IsMatch("1111.1"); // True
      res = decimalMatch.IsMatch("12111.221"); // False
      res = decimalMatch.IsMatch("11.21"); // True
      res = decimalMatch.IsMatch("11.2111"); // False
      res = decimalMatch.IsMatch("1121211.21143434"); // false
    

    【讨论】:

    • 谢谢!我还意识到使用正则表达式进行检查是最好的选择,因为无论如何我都在从字符串转换为十进制。我的正则表达式模式看起来像 "\.(\d{3})" 因为我只想检查字符串是否有超过 3 个小数,所以我猜这个模式就足够了。
    • 如果您的应用程序需要处理不同的文化,则不会
    • 很好的输入,但是对于不同的文化有一个正则表达式应该不是问题!
    【解决方案2】:

    我在 stackoverflow 中找到了解决方案:

    (由 carlosfigueira 发布:C# Check if a decimal has more than 3 decimal places?

        static void Main(string[] args)
        {
            NumberFormatInfo nfi = new NumberFormatInfo();
            nfi.NumberDecimalDigits = 2;
            decimal s;
            if (decimal.TryParse("2.01", NumberStyles.AllowDecimalPoint, nfi, out s) && CountDecimalPlaces(s) < 3)
            {
                Console.WriteLine("Passed");
                Console.ReadLine();
                return;
            }
            Console.WriteLine("Failed");
            Console.ReadLine();
        }
    
        static decimal CountDecimalPlaces(decimal dec)
        {
            int[] bits = Decimal.GetBits(dec);
            int exponent = bits[3] >> 16;
            int result = exponent;
            long lowDecimal = bits[0] | (bits[1] >> 8);
            while ((lowDecimal % 10) == 0)
            {
                result--;
                lowDecimal /= 10;
            }
            return result;
        }
    

    【讨论】:

      【解决方案3】:

      可能不像其他选项那样优雅,但我认为更简单:

              string test= "1,23"; //Change to your locale decimal separator
              decimal num1; decimal num2;
              if(decimal.TryParse(test, out num1) && decimal.TryParse(test, out num2))
              {
                  //we FORCE one of the numbers to be rounded to two decimal places
                  num1 = Math.Round(num1, 2); 
                  if(num1 == num2) //and compare them
                  {
                      Console.WriteLine("Passed! {0} - {1}", num1, num2);
                  }
                  else Console.WriteLine("Failed! {0} - {1}", num1, num2);
              }
              Console.ReadLine();
      

      【讨论】:

        【解决方案4】:

        或者你可以做一些简单的整数数学:

        class Program
        {
            static void Main( string[] args )
            {
                string s1 = "1.25";
                string s2 = "1.256";
                string s3 = "1.2";
        
                decimal d1 = decimal.Parse( s1 );
                decimal d2 = decimal.Parse( s2 );
                decimal d3 = decimal.Parse( s3 );
        
                Console.WriteLine( d1 * 100 - (int)( d1 * 100) == 0);
                Console.WriteLine( d2 * 100 - (int)( d2 * 100)  == 0);
                Console.WriteLine( d3 * 100 - (int)( d3 * 100 ) == 0 );
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-04-08
          • 1970-01-01
          • 2015-11-23
          • 1970-01-01
          • 2019-08-03
          • 2018-01-03
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多