从正则表达式中获取文本字段输入范围

本文关键字:字段 输入 范围 取文本 获取 正则表达式 | 更新日期: 2023-09-27 18:19:24

当文本框收到焦点时,我想显示屏幕上的键盘。我可以根据字段的输入范围显示几个键盘。问题是,文本框的预期用户输入是服务器驱动的,我没有提供输入范围属性(也不能添加一个)。实际上,我所拥有的只是用于验证用户输入字段的正则表达式。

基于任何正则表达式字符串,确定文本框的输入范围的最佳方法是什么?

输入范围为:Name(仅限字母键盘),PhoneNumber(仅限数字键盘)等。

典型的正则表达式:" ^[0 - 9]{4 4}$ "," ^[0 - 9]{10、10}$"但可能更加复杂。

从正则表达式中获取文本字段输入范围

将正则表达式映射硬编码为输入类型似乎是一种选择,但这是一种糟糕的选择。

你知道输入有多少类吗?我想你知道。您需要创建一个与各种输入类匹配的示例输入集,然后创建一个真值表进行比较,如

EXAMPLE      | PHONE | NAME | TEXT |   
2061234567   | T     | F    | T    |
206.123.4567 | T     | F    | T    |
hello        | F     | T    | T    |
brian        | F     | T    | T    |
bADSFj@$$    | F     | F    | T    |

获取字段的正则表达式,通过正则表达式运行示例字符串,并将匹配与不匹配与将真值映射到输入类的表进行比较。下面是一个示例解决方案,不过您可能希望使用一些启发式方法,而不是进行精确匹配。(Java):

int PHONE_CLASS = 0x18; // 11000 - the truth table value from above
...
Map<int, Keyboard> keyboardMap;
keyboardMap.put(PHONE_CLASS, phoneKeyboard);
...
Keyboard inferKeyboard(Pattern regex) {
  int matches = 0;
  for (String example : examples) {
    matches = matches << 1;
    if (regex.matches(example)) { matches++; }
  }
  if (!keyboardMap.containsKey(matches)) { return GENERIC_KEYBOARD; }
  return keyboardMap.get(matches);
}

诀窍是在正则表达式模式中的if条件中指定每个输入范围的格式。我从一个电话号码开始,因为它似乎是最有限的;数字、破折号、句号、斜杠)。然后我用自己的方式去找别人。注意,regex电话模式不是非常健壮,所以你可能需要调整它。找到之后,检查regex模式,看看哪些文本被放入命名匹配捕获组中。如果命名匹配捕获组有文本,中提琴!一个人已经确定了它是什么。

这个例子有三种类型,电话,地址(地址是数字,然后是空格,然后是文本),后面跟着默认的文本。但是你可以在内部添加更多的if。该模式被注释以方便使用。

void Main()
{
    Console.WriteLine ("303-867-5309".DetermineScope() == InputScope.Phone); // True
    Console.WriteLine ("1811 South Quebec Way".DetermineScope() == InputScope.Address); // True
    Console.WriteLine ("Turk 181".DetermineScope() == InputScope.Text); // True
}
public enum InputScope
    {
       Phone,           // Digits and dividers
       Address,         // number space then text
         Text,            // Everything is text...final catch all.
    };

public static class TestCaseExtensions
{
    public static InputScope DetermineScope(this string text)
    {
        string pattern = @"
(?(^['d.'-/'']+$)           # If: First check for phone; just numbers and dividers (no spaces)
   (?<Phone>['d.'-/'']+)    #    Place into Phone named capture group
 |                          # Else: start a new check
   (?(^'d+'s'w+)            # If Check for address (if Address)
     (?<Address>.*)       #    Looks like its an address, place into address capture group
    |                     # Else
     (?<Text>.*)          #   Nope just text, place into text capture group
   )
)";
    var result = InputScope.Text; // Default to the lowest...text
    // Ignore allows us to document pattern; it is not related to processing text.
    var match = Regex.Match(text, pattern, RegexOptions.IgnorePatternWhitespace);
    if (match.Success)
    {
        result = 
        Enum.GetValues(typeof(InputScope))
            .OfType<InputScope>()
            .Where (tp => match.Groups[tp.ToString()].Success)
            .First ();
    }
    return result;
    }
}

我已经写了更多关于这个主题的文章:正则表达式和If条件。