用正则表达式对文本框输入进行实时验证和格式化

本文关键字:实时 验证 格式化 输入 正则表达式 文本 | 更新日期: 2023-09-27 18:09:11

我有一个WPF应用程序,用户可以通过USB更改连接到计算机的产品的产品编号。产品贴纸上的产品编号格式为:111 22 33-44。

现在用户只能在文本框中输入数字(111223344)。使用检查9位数的regex对输入进行验证。但是现在客户端希望用户能够:

  1. 只输入数字,并按照输入的方式格式化字符串。当用户输入"1112"时,它应该自动在文本框中被格式化为"1112",以此类推。当用户输入所有9位数字时,它应该看起来像111 22 33-44
  2. 按照标签上的数字输入(有空格等)

但同时产品编号必须经过验证,只能包含9位数字。空格和"-"必须不可见

我可以很容易地在代码中解决这个问题,但这里的问题是,这个验证/格式化必须在配置文件中完全可配置。此应用程序可以为各种类别的产品提供服务,产品编号的格式可能会有所不同。

这是一个相当容易的方式解决与正则表达式?我真的不知道怎么把这两者结合起来,验证和格式化:

  • ^'d{9}$ -用于验证9位数字
  • (' w {3}) (' w {2}) ? (' w {2}) ? (' w {2}) ?-用于格式化和替换模式$1 $2 $3-$4。然而,该模式只格式化不带空格和"-"的9位数字

有什么建议吗?

编辑:

似乎我需要使用至少三种正则表达式模式来工作:

  1. 用于验证有效的产品编号(而不是显示值)。是9位数吗?
  2. 用于格式化显示值(123456789 = 12345 67-89)
  3. 从格式中剥离添加的字符(空格和-)

也许一个更简单的解决方案是保持当前验证(例如^'d{9}$)验证原始值,然后简单地添加一个名为DisplayMask的设置,负责配置的人可以输入这样的内容:

  • "### ## ##-##"

然后我编写代码,使用这个掩码来格式化显示值。这有几个优点:

  1. 对于负责配置的人员来说非常容易理解
  2. 这也将使我能够轻松地检索需要从输入值中剥离的所有字符,只需获得displaymask并删除所有#。剩下的字符是在写入产品硬件之前必须从产品编号中剥离的字符。
  3. 也可以很容易地设置文本框的最大长度。产品编号原始值的最大长度+显示掩码中添加的字符数。

用正则表达式对文本框输入进行实时验证和格式化

如果您想使其可配置,关键是System.Text.RegularExpressions名称空间中的Regex类。

将正则表达式存储在外部配置文件中可以很容易地导入并用于匹配,例如Regex.IsMatch(),特别是IsMatch(string, string)

看看previewtexttinput中的这个正则表达式:只有0.0和1.0之间的小数

您可以在这里使用PreviewTextInput事件,然后使用Regex.Replace设置格式,这里是一个示例

string inputStr = "111223";//e.Text;
inputStr = Regex.Replace(inputStr, @"'D", string.Empty);
if (inputStr.Length > 0)
{
    inputStr = inputStr.Substring(0, Math.Min(9, inputStr.Length));
    List<string[]> tmp = new List<string[]>() { new string[] { "7", "-" }, new string[] { "5", " " }, new string[] { "3", " " } };
    foreach (var arr in tmp)
    {
        inputStr = Regex.Replace(inputStr, @"(?<=^'d{" + arr[0] + "})", arr[1]);
    }
}
Console.WriteLine(inputStr);

首先,在文本格式化之后,您有一个长度为12的条目。我会设置TextBox.MaxLength = 12来限制可以输入的数据量。

就验证而言,可能有一种"更干净"的方法,但首先您可以使用一系列Regex.IsMatch()条件来自动格式化输入。

例如:

1112       => 111 2
111 223    => 111 22 3
111 22 334 => 111 22 33-4

然后是最后的Regex.IsMatch()检查输入的格式是否为

### ## ##-##

代码示例:

private void textBox1_TextChanged(object sender, EventArgs e)
{
    string text = textBox1.Text;
    if (Regex.IsMatch(text, "''d{4}"))
    {
        textBox1.Text = Regex.Replace(text, "(''d{3})(''d)", "$1 $2");
    }
    else if (Regex.IsMatch(text, "''d{3} ''d{3}"))
    {
        textBox1.Text = Regex.Replace(text, "(''d{3} ''d{2})(''d)", "$1 $2");
    }
    else if (Regex.IsMatch(text, "''d{3} ''d{2} ''d{3}"))
    {
        textBox1.Text = Regex.Replace(text, "(''d{3} ''d{2} ''d{2})(''d)", "$1-$2");
    }
    else if (!Regex.IsMatch(text, "''d{3} ''d{2} ''d{2}-''d{2}"))
    {
        // Invalid entry
    }
    // Keep the cursor at the end of the input
    textBox1.SelectionStart = textBox1.Text.Length;
}