为什么RegularExpressionValidator不匹配我的正则表达式?

时间:2016-07-29 16:35:40

标签: regex webforms

我在尝试使用asp:TextBox验证asp:RegularExpressionValidator控件时遇到问题。我已经简化了我正在使用的正则表达式并且已经隔离了RegularExpressionValidator在这部分上失败了:(?=(.*[A-Z]){2}),我不知道为什么。

正则表达式的这一部分要求输入包含至少两个大写字母。我使用LINQPad在

Regex.Match("THis", "(?=(.*[A-Z]){2})").Dump();

还有两个在线正则表达式测试人员,并且它们都适用于所有人。

根据MSDN documentation中的“备注”部分,RegularExpressionValidator类在客户端上使用JScript正则表达式语法。我找不到任何对JScript正则表达式语法的引用,所以我认为它们意味着JavaScript,并使用此Online regex tester对JavaScript测试正则表达式,这表明它适用于JavaScript。

2 个答案:

答案 0 :(得分:3)

重点是RegularExpressionAttribute需要完整的字符串匹配。它没有记录,但C# source code非常有说服力:

override bool IsValid(object value) {
    this.SetupRegex();

    // Convert the value to a string
    string stringValue = Convert.ToString(value, CultureInfo.CurrentCulture);

    // Automatically pass if value is null or empty. RequiredAttribute should be used to assert a value is not empty.
    if (String.IsNullOrEmpty(stringValue)) {
        return true;
    }

    Match m = this.Regex.Match(stringValue);

    // We are looking for an exact match, not just a search hit. This matches what
    // the RegularExpressionValidator control does
    return (m.Success && m.Index == 0 && m.Length == stringValue.Length);
}

请参阅 //我们正在寻找完全匹配,而不仅仅是搜索匹配。这与RegularExpressionValidator控件的作用相匹配

因此,您必须在正则表达式中添加消费 .*部分模式,因为您的(?=(.*[A-Z]){2})仅匹配部分,它匹配字符串开头的空格,如果字符串中有2个大写ASCII字母,则不满足m.Length == stringValue.Length条件。

实际上,它可以更好地编写为

^(?:[^A-Z]*[A-Z]){2}.*$

请参阅regex demo(似乎^(字符串的开头)和$(字符串结尾)锚点在代码中是多余的,模式锚定在代码中)

<强>详情:

  • ^ - 字符串开头
  • (?:[^A-Z]*[A-Z]){2} - 2个序列:
    • [^A-Z]* - 除ASCII大写字母以外的零个或多个字符
    • [A-Z] - 一个大写的ASCII字母
  • .* - 除换行符之外的任何零个或多个字符
  • $ - 字符串结尾

答案 1 :(得分:0)

为了使用RegularExpressionValidator,我需要在表达式的末尾添加.*

(?=(.*[A-Z]){2,}).*

Regular expression visualization

Debuggex Demo

更新

Wiktor's answer解释了添加.*的原因。 Viktor表示该模式可以更好地编写为^(?:[^A-Z]*[A-Z]){2}.*$,但我没有遵循这一点,因为我需要在表达式中添加其他部分以实现其他一些规则,例如“必须包含至少两个小写字母“,需要使用正向前看;使用非捕获组不会促进这一点。