DataAnnotation RegularExpression问题

时间:2017-12-03 18:16:57

标签: c# regex asp.net-mvc validation data-annotations

为什么RegularExpressionAttribute验证不会将输入字符串与连接的所有匹配项的值进行比较?

我在这里问了一个关于下面情况的问题,但是我在第二天找到了一个解决方案,发现在这里提出问题会更好。

[Required(
    AllowEmptyStrings = false,
    ErrorMessage = "Required")]
[RegularExpression(
    "^[^0]{1}|..+",
    ErrorMessage = "Expressao Regular")]
public string EncryptedValue { get; set; }

除了空字符串或“0”外,该属性在ModelState中应该有效,但是:

enter image description here

您可以测试HERE表达式和值。

表达
^[^0]{1}|..+


+iCMEBYZQtWbnU2RPX/MmqrDPuVJzSGGWhkFd+9/zpMbHVoOlZFuF9ND1xAxsQy3YFCPIsUBEgg2RJNkPefrmQ==

您会注意到表达式匹配,但有两个匹配。第一个匹配本身不等于输入字符串,您需要连接两个匹配值才能达到该值。

但显然这不是在ModelState的验证中完成的,即使使用jquery.validate.unobtrusive也会发生这种情况(使用jquery,我需要点击提交按钮两次才能看到这一点,但它确实发生了。)

解决方案
您需要在第一个匹配中构建一个完全匹配输入字符串的表达式。

构建表达式以验证字段时,表达式中的每个OR必须与所有输入字符串匹配。

因此,无论何时使用OR运算符挂载表达式,始终从最大输入安装到最小输入。

在这种情况下:
^[^0]{1}|..+..+|^[^0]{1}

2 个答案:

答案 0 :(得分:2)

让我们来看看System.ComponentModel.DataAnnotations.RegularExpressionAttribute类。我们对以下方法感兴趣:

 [__DynamicallyInvokable]
public override bool IsValid(object value)
{
  this.SetupRegex();
  string input = Convert.ToString(value, (IFormatProvider) CultureInfo.CurrentCulture);
  if (string.IsNullOrEmpty(input))
    return true;
  Match match = this.Regex.Match(input);
  if (match.Success && match.Index == 0)
    return match.Length == input.Length;
  return false;
}

在我们的例子中,我们有正则表达式" ^ [^ 0] {1} | .. +" 和输入字符串 + iCMEBYZQtWbnU2RPX / MmqrDPuVJzSGGWhkFd + 9 / zpMbHVoOlZFuF9ND1xAxsQy3YFCPIsUBEgg2RJNkPefrmQ == 。正则表达式验证返回两个匹配,第一个 + (第一个符号),第二个是其余部分。第一个匹配长度小于输入字符串,这就是IsValid返回false的原因。

为什么RegularExpressionAttribute验证不会将输入字符串与连接的所有匹配项的值进行比较?因为它适用于第一场比赛

答案 1 :(得分:0)

所以,如果你的正则表达式是^[^0]{1}|..+

你重视的是:+iCMEBYZQt...

一次匹配+,另一次匹配:iCMEBY0ZQt...

问题是,在第一部分^[^0]{1}中,你的正则表达式尝试匹配任何非0的字符,一次(在行/字符串的开头)。 因此,正则表达式看起来像字符串,并说:

  

Voilah !!我有一些不是零的东西,在开头是一个字符,字符是:+,谢谢,谢谢,我的饼干在哪里?!

此外,或指令(|)告诉正则表达式对模式更灵活,就像如果你找不到第一个表达式,不要感觉很糟糕,你也可以寻找另一件事。但是一旦正则表达式有了第一个cookie就没有意义回去尝试再次寻找第二个表达式(..+)因为已经为第一个表达式找到了解决方案,并且正则表达式知道同一个工作不会有额外的cookie。所以,生活还在继续,我们必须继续前进。

在这里你可以看到第一个和第二个表达式是满足正则表达式的独立方式。

Regex with Or

https://regex101.com/r/UWtcF8/3

<小时/> 你的第二个正则表达式是:..+|^[^0]{1}

Second regex with Or

https://regex101.com/r/la3wDa/1

交换表达式的顺序。这是相同的,但正则表达式试图满足的第一个表达式是..+,它基本上给出了涉及2个或更多字符的任何内容。例如,如果您有00,正则表达式会说:

  

Yumm,cookies!

这可能没关系,这取决于你想要解决的问题。

现在另一种选择是:

^(?!0$).+

Regex with negative lookahead

https://regex101.com/r/gxJdch/1

我们将寻找除a single zero之外的任何内容。

<小时/> 有用和有趣的链接: https://regex101.com/&lt;即使您不使用php,也可以选择php版本并查看regex debugger以了解有关正则表达式的更多信息!) https://regexper.com/