【问题标题】:Getting text field input scope from regex从正则表达式获取文本字段输入范围
【发布时间】:2012-01-05 00:43:22
【问题描述】:

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

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

输入范围为:姓名(仅限字母键盘)、电话号码(仅限数字键盘)等

典型的正则表达式:“^[0-9]{4,4}$”、“^[0-9]{10,10}$”,但可能要复杂得多。

【问题讨论】:

  • 你必须澄清你在做什么。如果正则表达式只能在用户输入文本后应用,那么 InputScope 的意义何在?
  • 反转正则表达式以查看它是否期望字符串或数字将是矫枉过正。只需有一个字段列表,如果值应该是字符串或数字,然后使用该列表来确定要显示的键盘。
  • 我正在使用正则表达式来验证提交时的用户输入,我还想用它来显示正确的键盘焦点。
  • 你怎么知道哪个正则表达式去哪个文本框?
  • 那么如果你提前知道了哪个正则表达式属于哪个文本框,那你就不知道那个文本框需要什么输入范围了吗?

标签: c# .net regex


【解决方案1】:

将正则表达式映射硬编码为输入类型似乎是一种选择,但效果不佳。

你知道有多少种输入吗?我会假设你这样做。您需要创建一个与各种输入类匹配的输入样本集,然后制作一个真值表进行比较,例如

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);
}

【讨论】:

    【解决方案2】:

    诀窍是在正则表达式模式中的 if 条件内为每个输入范围指定格式。我从电话号码开始,因为它似乎是最具限制性的;数字,破折号,句号斜线)。然后我按照自己的方式工作给别人。 请注意,正则表达式电话模式不是超级健壮,因此您可能需要对其进行调整。。找到后,检查正则表达式模式以查看将哪些文本放入命名匹配捕获组中。如果命名匹配捕获组有文本,中提琴!已经确定了它是什么。

    这个例子有三种类型,电话、地址(地址是数字,然后是空格,然后是文本),然后是默认的文本。但是您可以在内部添加更多 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;
    
        }
    
    }
    

    我已经写了更多关于这个主题的文章:Regular Expressions and the If Conditional

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-10-05
      • 2019-05-29
      • 2013-04-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多