DataAnnotation 正则表达式问题

Posted

技术标签:

【中文标题】DataAnnotation 正则表达式问题【英文标题】:DataAnnotation RegularExpression problems 【发布时间】:2018-05-17 05:24:30 【问题描述】:

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

我在这里问了一个关于以下场景的问题,但第二天我找到了解决方案,发现在这里提出问题更好。

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

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

你可以测试HERE的表达式和值。

表达式^[^0]1|..+@987654327 @

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

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

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

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

因此,每当您使用 OR 运算符挂载表达式时,始终从最大输入到最小输入进行挂载。

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

【问题讨论】:

是RegularExpressionAttribute的代码吗?默认情况下,该模式是“锚定”的。 你能解释一下你想用你当前的正则表达式获取/匹配(或不匹配)什么吗? "^[^0]1|..+" - 空字符串或“0”除外。你确定吗 ?对我来说,这个很好用 "^(?!0|\s|^$)" @mayo,不是零或一切。 @Z.R.T.,你知道 [Required(AllowEmptyStrings = false)] 做什么,对吧? 【参考方案1】:

让我们看一下 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 验证不将输入字符串与所有连接匹配的值进行比较?因为它适用于第一场比赛

【讨论】:

【参考方案2】:

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

而你的价值是:+iCMEBYZQt...

一个匹配将是+,另一个匹配:iCMEBY0ZQt...

问题是,在第一部分^[^0]1,您的正则表达式尝试匹配任何不是0 的字符,一次(在行/字符串的开头)。 因此,正则表达式会查看字符串并说出如下内容:

瞧!!我有一个不是零的东西,一开始是一个字符,字符是:+,谢谢,谢谢,我的cookie在哪里?!

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

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

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


您的第二个正则表达式是:..+|^[^0]1:

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

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

好吃,饼干!

这可以好还是不好,这取决于您要解决的问题。


现在另一个选择是:

^(?!0$).+

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

除了a single zero,我们将在哪里寻找任何东西。


有用和有趣的链接: https://regex101.com/ regex debugger 以了解有关正则表达式的更多信息!) https://regexper.com/

【讨论】:

我认为这是另一个问题,建议的正则表达式只丢弃一个只有唯一零的字符串。不要对电子邮件或电话号码进行任何形式的控制。对于电子邮件验证,我建议阅读:***.com/questions/5342375/regex-email-validation,这也是关于电话号码的一个很好的答案:***.com/questions/18091324/…! 为什么不考虑 OR 运算符? 嗯,我认为这只是看待问题的另一种方式。因为您正在寻找not zero or anything,这就像everything but if you find a zero discard the value(这可能是提前返回的类似想法)。使用 Or 也是有效的! 我不认为性能是这里的答案。正则表达式用于查找某些内容。因为foreach而限制工具,对我来说听起来没有必要,这很不常见,但有可能。那么,为什么不呢。 limit the tool because a foreach 是什么意思?

以上是关于DataAnnotation 正则表达式问题的主要内容,如果未能解决你的问题,请参考以下文章

php 正则表达式正则表达式一般表

使用正则表达式删除表 - MySQL

使用正则表达式查找哈希表/字典/地图

正则表达式表

使用正则表达式解析表 - Java

正则表达式创建 AWS Athena 表 (RegexSerDe)