文本框检查Regex表达式不允许小数

时间:2013-07-22 21:36:53

标签: c# regex winforms validation textbox

我想创建一个TextChanged事件,检查输入文本是否符合特定条件,如果没有,则删除最后输入的字符。在这种情况下,标准是数字,1个小数和1个分数。

我正在测试正则表达式只是为了数字和小数而遇到了问题。我已经尝试了几种不同的表达方式(我写自己很糟糕,因此它们可以从各种其他堆栈溢出问题中获取),结果每次都是相同的。它接受数字就好了,但它不接受小数。任何帮助将不胜感激!

        string isNumber = @"^\d{1,9}(\.\d{1,9})?$";

        private void TextBox_TextChanged(object sender, EventArgs e)
        {
            TextBox text = (TextBox)sender;

            Match match = Regex.Match(text.Text, isNumber);

            if (!match.Success)
            {
                if (text.Text.Length > 1)
                    text.Text = text.Text.Substring(0, text.Text.Length - 1);
                else
                    text.Text = "";

                text.Select(text.Text.Length, 0); //set cursor to the end 
                                                  //of the string
            }
        }

3 个答案:

答案 0 :(得分:6)

我认为问题在于您尝试逐个字符地验证用户类型的数字,但是如果没有值为无效值临时,则无法键入有效的十进制数字

考虑当用户键入值1.2时会发生什么:

  1. 用户键入字符1
  2. 验证会因为文本框的值发生更改而触发。
  3. 1是有效的小数,因此验证通过。
  4. 用户继续输入,添加小数点字符.
  5. 验证再次触发,因为文本框的值已更改。
  6. 1.根据正则表达式不是有效小数,因此最后一个字符将被删除。
  7. 文本框的值现在返回1
  8. 用户感到沮丧。转到第4步。
  9. 如您所见,无法输入小数点。但是,如果您尝试更改正则表达式以允许小数点存在而没有后续数字,那么如果用户在键入小数点后停止然后提交表单,则可能会出现无效值。

    所以重点是,使用逐个字符的验证方案将不适用于小数。更好的方法是允许用户在框中输入他们想要的内容,然后在用户完成输入后进行验证。您可以通过验证文本框何时失去焦点或何时提交表单来执行此操作。

答案 1 :(得分:1)

这不是最漂亮的,但它似乎做你需要的:

^(\d{1,9}\.|)\d{1,9}(\.(\d{1,9})?)$

我应该注意,这对于以小数开头的数字不起作用。

答案 2 :(得分:1)

至少有一个问题是你要做什么(以及怎么做)(比如brian指出这么好),你可能意味着只允许文本框的前3个字符为格式“1.3”的东西,例如并删除char,如果它不是那个位置的正确的。 如果您真的打算这样做,您可以这样做(如果用户在成功后放置另一个字符,在这种情况下是第四个字符,我没有为该案例放置任何代码):

        string isNumber = @"^[1-9]{1}\.[1-9]{1}$";
        private void textBox1_TextChanged(object sender, EventArgs e)
        {
            TextBox text = (TextBox)sender;

            Match match;

            switch (text.Text.Length)
            {
                case 1:
                    if (char.IsDigit(text.Text[0]))
                        break;
                    else
                        text.Text = "";
                    break;
                case 2:
                    if (char.IsPunctuation(text.Text[1]))
                        break;
                    else
                    {
                        text.Text = text.Text.Remove(text.Text.Length - 1, 1);
                        text.Select(text.Text.Length, 0); 
                    }
                    break;
                case 3:
                    match = Regex.Match(text.Text, isNumber);
                    if (!match.Success)
                    {
                        text.Text = text.Text.Remove(text.Text.Length - 1);
                        text.Select(text.Text.Length, 0); 
                    }
                    else
                        MessageBox.Show("Success!!!!!");
                    break;
            }

        }

如你所见,我通过char检查char,直到它长度达到3,然后我检查正则表达式。