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

时间:2012-01-05 00:43:23

标签: c# .net regex

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

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

输入范围是:名称(仅限字母键盘),PhoneNumber(仅键盘数字)等。

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

2 个答案:

答案 0 :(得分:3)

将正则表达式的地图硬编码为输入类型似乎是一种选择,但是很差。

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

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    |

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

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

答案 1 :(得分:0)

诀窍是在正则表达式模式中的if条件中指定每个输入范围的格式。我从一个电话号码开始,因为它似乎是最有限的;数字,短划线,句号斜线)。然后我按照自己的方式去做别人。 请注意,正则表达式手机模式不是非常强大,因此您可能需要进行调整。。找到后检查正则表达式模式以查看将哪些文本放入指定的匹配捕获组。如果指定的匹配捕获组有文本,中提琴!一个人已经确定了它是什么。

此示例有三种类型,电话,地址(地址是数字,然后是空格,然后是文本),后跟默认的文本。但是你可以在内部添加更多ifs。评论模式以便于使用。

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