在开发桌面应用程序时,经常需要用户输入特定格式的数据,如IP地址。本文将介绍如何使用正则表达式和简单的逻辑来验证用户在文本框中的按键输入,确保输入符合预设的字符串模式。
在开发过程中,需要一种简单的方法来允许用户在IP地址框中输入字符,同时只允许他们根据光标位置输入正确的字符。虽然正则表达式非常适合验证最终的字符串,但它们无法验证正在输入的字符串的中间部分。本文提供的代码和模式解决了这个问题。
下面是一个演示窗口,展示了这些类。六个文本框将只接受其各自标签指定的适当按键。当文本框的字符串完全有效且完整时,复选框将被选中。
窗口背后的主要代码非常简单。每当文本框的TextChanged事件触发时,复选框就会被设置。
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void sbIPv4_TextChanged(object sender, EventArgs e)
{
cbIPv4.Checked = ((StringBox.StringBox)sender).IsComplete();
}
// 其他TextChanged事件处理...
}
验证按键以匹配特定模式是一个两步过程。第一步是基于光标位置检查只接受适当的字符。例如,IP地址由四个以点分隔的十进制字节组成,每个部分的范围是0-255。可以轻松创建正则表达式模式来实现这一点。
为了解决这个问题,改变了模式,使其匹配完整IP地址的所有可能的较短版本。可能会使用以下模式:
[\d]{0,3}[.]?[\d]{0,3}[.]?[\d]{0,3}[.]?[\d]{0,3}
使用此模式,无论输入了多少字符串,只要数字和点在其正确的位置,都会得到匹配。现在让看看在基类StringBox中使用此模式的按键代码:
private void StringBox_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.Handled) return;
// 插入键入的字符到临时字符串
var temp = SelectionLength > 0 ?
Text.Substring(0, SelectionStart) + e.KeyChar +
Text.Substring(SelectionStart + SelectionLength) :
Text.Insert(SelectionStart, e.KeyChar.ToString());
// 如果模式不匹配或长度不正确,则通过设置handled = true来拒绝按键
var handled = !(regex.IsMatch(temp) && (regex.Match(temp).Length == temp.Length));
// 进行额外的检查以确保各个部分正确
if (!handled)
handled = !IsValid(temp);
e.Handled = handled;
}
查看下面的StringIPv4类代码:
public class StringIPv4 : StringBox
{
public StringIPv4()
{
Pattern = @"[\d]{0,3}[.]?[\d]{0,3}[.]?[\d]{0,3}[.]?[\d]{0,3}";
}
public override bool IsComplete()
{
// 确保有4个部分
var s = Text.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
return s.Length == 4;
}
protected override bool IsValid(string str)
{
// 确保每个部分的范围限制在0-255之间
var s = str.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
foreach (var t in s)
{
var x = Convert.ToInt32(t);
if (x < 0 || x > 255)
return false;
}
return true;
}
}
首先,看到这个类是从StringBox类派生的,并在构造函数中定义了正则表达式模式。IsValid函数覆盖了基类中的虚拟函数。这个函数将temp字符串分割成由点分隔的独立部分,并检查每个部分是否限制在0-255的范围内。如果值不在该范围内,则返回false,这将拒绝按键。
IsComplete函数通常由应用程序调用以检查Text字符串是否完整且准备就绪。在这种情况下,只需要检查字符串中是否有4个字节。IsValid已经检查了每个部分的范围限制。另一种方法是将Text解析为InterNetwork类型的IP地址。然后,完整的字符串就是一个完全有效的IPv4地址。
要创建一个新的StringBox类:
创建此代码向展示了一种使用非传统正则表达式的新方法。基本上,如何使用一个似乎匹配字符串以及模式的所有子字符串的正则表达式。或者如何使用正则表达式进行不仅仅是完整字符串验证。