正则表达式无法过滤 WinForms 中的 TextBox 字符

Posted

技术标签:

【中文标题】正则表达式无法过滤 WinForms 中的 TextBox 字符【英文标题】:Regex does not work to filter TextBox characters in WinForms 【发布时间】:2016-05-21 11:37:29 【问题描述】:

我想创建一个 TextBox (WinForms),它只接受正数或负数以及末尾任意数量的字符“k”,我认为模式是^-?[0-9]+k*$

我想阻止用户写入任何与该表达式不匹配的字符。这是我已经实现的类:

public class NumTextBox : TextBox 

        private Regex regex;

        public NumTextBox() : base() 
            regex = new Regex(@"^-?[0-9]+k*$");
        

        protected override void OnKeyPress(KeyPressEventArgs e) 
            String s = Text + e.KeyChar; // current text + new character
            if (!regex.Match(s).Success) 
                e.Handled = true;
             else 
                e.Handled = false;
            
            base.OnKeyPress(e);
        
   

这样,TextBox 不允许你在文本的开头写字符,但它允许你在某个数字之后写它们,我的意思是:

asd -> 不允许

123asd -> 允许,这不应该被允许

我也尝试将结束字符添加到s,但它不起作用。

编辑: 我在调试器中看到字符串s 末尾有新字符。

编辑 2

为什么不直接尝试解析 TextBox 的 Text 值?

因为我想根据正则表达式阻止用户写入不允许的字符。

代码还有一些其他问题: 1.如果用户开始输入负数,它应该不起作用,因为(-)本身不匹配。 2. 如果文本是 123 并且用户在 1 和 2 之间单击然后按 k 怎么办?(按键不是这个的好地方)

1:我认为你是对的,但我更愿意现在解决这个问题,以后再处理。

2:数字之间不应允许字母“k”,只能在数字末尾。

如果您调试代码,正则表达式是否匹配并单步执行 e.Handled=true?此外,OnTextChanged 可能是更好的覆盖方法。

    如果我调试代码,正则表达式匹配(说它是正确的)错误字符串(例如 123asd),因此它不会进入 e.Handled = true

    我认为您指的是覆盖OnTextChanged 并删除最后写入的字符,如果它与正则表达式不匹配,不是吗?在那种情况下,我看到的一个问题是文本指针返回到开头。

【问题讨论】:

你的regex is correct。 我从你的描述中不明白是什么不起作用。但是,我发现实施存在一些问题。该代码假定新字符将添加到文本的末尾,但仅当光标位于文本末尾时才为真。另外,如果用户以减号开头写入负数,则字符串“-”是无效输入。 ...当然还有阻止用户粘贴到TextBox的问题。 你为什么不直接TryParse TextBox 的Text 值? 该代码还有一些其他问题: 1. 如果用户开始输入负数,它应该不起作用,因为 (-) 本身不匹配。 2. 如果文本是 123 并且用户在 1 和 2 之间单击然后按 k 怎么办?(按键不是一个好地方) 【参考方案1】:

我相信您的问题在这里:

string s = Text + e.KeyChar; // current text + new character

问题在于它会附加新字符,而不管光标位置如何。这意味着如果您转到字符串的开头并输入“k”,那么Handled 不会触发,因为您说 + 'k',这很好,根据正则表达式。

它远非完美,但您可以通过以下方式处理OnTextChanged,以满足您的需求。我只是简单地测试了它,但据我所知,它似乎产生了所需的行为。

protected override void OnTextChanged(EventArgs e)

    if (string.IsNullOrEmpty(this.Text))
        return;

    int pos = this.SelectionStart;

    if (!regex.IsMatch(Text))
    
        this.Text = _OldValue;
        this.SelectionStart = pos > 0 ? pos - 1 : pos;
    
    else
        _OldValue = this.Text;

    base.OnTextChanged(e);

你可以看到我做了一个 hack 来解决光标返回到你在帖子或评论中提到的字符串开头的问题。

【讨论】:

【参考方案2】:

你可以做的是检查哪个键被按下,如果它是正确的,那么你应该添加它

你的例子是这样的:

int temp;
if(int.TryParse(e.KeyChar,out temp) || e.KeyChar == '-' || e.KeyChar == 'k')

//code

【讨论】:

是的,目前我正在遵循这种方式。但是使用这种方法,我认为检查字母“k”是在数字之间还是在末尾是不必要的复杂。 无论放在哪里都可以在最后添加 但我想做的是允许123kkk之类的字符串,而不是12kk34kkk

以上是关于正则表达式无法过滤 WinForms 中的 TextBox 字符的主要内容,如果未能解决你的问题,请参考以下文章

我无法理解如何在 c# 中使用正则表达式或如何解决我的问题

正则表达式过滤日志

Winforms 文本框允许用户只输入字母、数字、点和单词之间的空格。正则表达式

弹簧控制器中的正则表达式

使用正则表达式过滤列表 [重复]

LogQL 中的正则表达式 JSON 过滤