正则表达式无法过滤 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 字符的主要内容,如果未能解决你的问题,请参考以下文章