【问题标题】:Validating user input of decimal number验证十进制数的用户输入
【发布时间】:2015-09-09 14:48:25
【问题描述】:

我有一个 wpf 文本框,我想在用户输入时检查他们是否只使用 0 1 2 3 4 5 6 7 8 9 。十进制数的[小数点]字符。我稍后使用此文本框转换为小数

我以以下文章为起点 Regex MatchPreview Text Input exampleregex-to-allow-one-decimal-number-or-a-range-of-decimal-number

这是我的 xaml

<TextBox Grid.Column="1" Height="28" HorizontalAlignment="Left" Margin="10,10,0,0" Name="tbTaxFreeLimit" Width="90" VerticalAlignment="Top" 
                                             AcceptsTab="True" 
                                             PreviewTextInput="tbDecimalCheck_PreviewTextInput"
                                            />

还有 c#

private void tbDecimalCheck_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
     // Test for decimal
     if (IsNumeric(e.Text)==false)
         e.Handled = true;
}

private bool IsNumeric(string s)
{
    Regex r = new Regex(@"^[0-9]");

    return r.IsMatch(s);
}

这个例子适用于 0 1 2 3 4 5 6 7 8 9 但我不能输入小数点。

如果我将下面的代码更改为以下代码,则无效

Regex r = new Regex(@"^[0-9].");

【问题讨论】:

  • 如何使用decimal.Parse 而不是具有适当文化设置的正则表达式?在这种情况下,正则表达式不是最好的方法。
  • 而不是正则表达式尝试将输入值实际转换为decimal。如果失败 - 显示红色边框。
  • @SonerGönül 更好decimal.TryParse

标签: c# regex wpf


【解决方案1】:

您的正则表达式^[0-9]. 表示从字符串的开头匹配0-9 范围内的一个字符,然后匹配任何字符(. 表示任何字符)。那不是你想要的。您需要匹配任意数量的字符、一个可选的小数点,然后是更多的数字。比如:

^\d+\.?\d*$

表示 1 个或多个 (+) 数字(\d 等同于 [0-9])、0 或 1 个 (?) 小数点(. 必须转义以匹配文字 @ 987654331@,因此是 \.),然后是 0 个或多个 (*) 位。

这修复了您的正则表达式,但是在文本输入上执行此操作有点痛苦,您最好让用户输入文本,然后使用 decimal.TryParse 之类的内容进行验证,而不是在他们输入时尝试限制。为什么?考虑用户输入:

1     // this is valid

然后:

1.    // this is still valid

然后:

1.2   // still valid

然后他们意识到他们的意思是2.2,那么他们会做什么呢?他们删除了1 给:

.2     // Buzzzz, not valid

这对用户来说真的很烦人。用户尝试删除1 并且控件顽固地拒绝更改。为什么?用户不知道。不要将输入用户输入变成“猜猜规则是什么”的游戏。

要考虑的另一件事可能对您来说可能是问题,也可能不是问题,那就是并非所有文化都使用. 作为小数分隔符。其实most of the world doesn't

所以不要取消文本输入,使用TryParse(具有适当的文化设置)并在TextBox 上设置一个错误,而不是停止用户输入文本。只是不要让用户进入下一阶段,直到他们解决了数字输入的问题。

【讨论】:

  • 感谢您的精彩回答和解释。我的目的是确保对输入的控制,但我可以看到它真的会让用户感到沮丧。我使用 TryParse 方法进行最终验证,因此我需要对其进行扩展。错误是指在文本框旁边显示一个十字图标,并带有错误原因的工具提示?
  • @IanW:是的。控件周围的红色边框是指示错误的非常常见的元素。如果用户不明白问题所在,工具提示也很有用。
  • 非常感谢您的提示
【解决方案2】:

正则表达式可能不是执行此操作的最易读/可维护的方式。

尝试解析它;

private bool IsNumeric(string s) => decimal.TryParse(s, out var value);

【讨论】:

    【解决方案3】:

    类似:

    Regex r = new Regex(@"^\d+\.?\d*$");
    

    解释:“^”匹配字符串的开头; \d+ 匹配一个或多个数字,\.?匹配一个可选的小数点,\d* 匹配零个或多个数字。 "$" 匹配字符串的结尾。

    【讨论】:

      【解决方案4】:
      System.Text.RegularExpressions.Regex.IsMatch(txtTransactionAmount.Text, @"[^0-9].[^0-9]")
      

      【讨论】:

      • 请考虑添加至少一些解释,好像为什么这回答了这个问题
      猜你喜欢
      • 2016-11-15
      • 1970-01-01
      • 1970-01-01
      • 2012-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-21
      相关资源
      最近更新 更多