【问题标题】:Why order matters in this RegEx with alternation?为什么在这个 RegEx 中顺序很重要?
【发布时间】:2012-04-20 15:06:20
【问题描述】:

TextBox 控件的要求是接受以下作为有效输入:

  1. 一个数字序列。
  2. 文字字符串“房间数”。
  3. 根本没有值(留空)。根本不指定值应该允许 RegularExpressionValidator 通过。

以下 RegEx 产生了预期的结果(成功验证了 3 种类型的输入):

"Number of rooms|[0-9]*"

但是,当一位同事询问为什么在指定字符串“房间数”时以下内容无法验证(要求 #2)时,我无法做出解释:

"[0-9]*|Number of rooms"

关于为什么在这种情况下交替的顺序很重要的解释确实非常有见地。

更新:

第二个正则表达式成功匹配控制台应用程序中的目标字符串“房间数”,如here 所示。但是,当输入为“房间数”时,在 aspx 标记中使用相同的表达式不匹配。这是相关的 aspx 标记:

<asp:TextBox runat="server" ID="textbox1" >
</asp:TextBox>

<asp:RegularExpressionValidator ID="RegularExpressionValidator1" 
EnableClientScript="false" runat="server" ControlToValidate="textbox1" 
ValidationExpression="[0-9]*|Number of rooms" 
ErrorMessage="RegularExpressionValidator"></asp:RegularExpressionValidator>

<asp:Button ID="Button1" runat="server" Text="Button" />

【问题讨论】:

  • 对于A sequence of numbers.,您应该使用\d+[0-9]+,而不是[0-9]*,因为这意味着任何位数(包括)。
  • 在一种情况下,您有“房间数”,而在另一种情况下,您有“行数”。是不是打错字了?
  • @Oded:但是它不会与第 3 项中的空字符串匹配。
  • @MartinLiversage - 它会,因为空字符串根本没有数字。
  • 你不需要^$ 来使它成为一个有意义的正则表达式吗? [0-9]* 将匹配任何字符串,否则,对吗? (或者验证器是否强制整个字符串匹配?)

标签: asp.net .net regex


【解决方案1】:

顺序很重要,因为这是 Regex 引擎尝试匹配的顺序。

案例一:Number of rooms|[0-9]*

在这种情况下,正则表达式引擎将首先尝试匹配文本“房间数”。如果失败则尝试匹配数字或什么都不匹配。

案例2:[0-9]*|Number of rooms

在这种情况下,引擎将首先尝试匹配数字或不匹配。但没有什么会总是匹配。在这种情况下,它永远不需要尝试“房间数”

这有点像 || C# 中的运算符。一旦左侧匹配右侧将被忽略。

更新: 回答你的第二个问题。它与 RegularExpressionValidator 的行为不同,因为它不仅仅是检查匹配。

// .....
Match m = Regex.Match(controlValue, ValidationExpression);
return(m.Success && m.Index == 0 && m.Length == controlValue.Length); 
// .....

它正在检查匹配并确保匹配的长度是整个字符串。这排除了部分匹配或空匹配。

【讨论】:

  • 谢谢。但是如果没有什么总是匹配的并且“它永远不需要尝试“房间数””,那么为什么在指定字符串“房间数”时它会失败?
  • 因为空字符串将匹配“房间数”的开头。带有 * 的正则表达式总是可以匹配 0 个东西。
  • 如果字符串“房间数”的开头证明是空字符串的“匹配”,为什么 RegEx 会失败?
  • 它不会失败。它只匹配空字符串。如果你运行这个code,它将显示它确实成功了。
  • 你是对的。它不会在控制台应用程序中失败,但奇怪的是,当在 aspx 标记中指定相同的正则表达式时,它无法匹配输入的“房间数”。请参考更新后的问题。
【解决方案2】:

关键是,如果您先指定,开头的 [0-9]* 将匹配空字符串。
如果您指定 整个字符串 应该是数字,那么它应该可以工作:

^[0-9]*$|Number of rooms

除非您指定^$,以表明整个字符串 必须匹配,否则将在“房间数”的开头匹配一个空字符串,并在那一点,第二个选择将不会被尝试。
我希望这能在评论中回答你的问题,我不确定它是否清楚......

【讨论】:

  • 谢谢。这样可行!但是,即使它尝试匹配与输入字符串“房间数”不匹配的空字符串,为什么它不尝试其他选择?
  • 这似乎是一个asp.net特有的问题,似乎困扰了我对正则表达式的理解。结帐更新的问题
【解决方案3】:

您可能想使用正则表达式Number of rooms|[0-9]+[0-9]+|Number of rooms,因为模式[0-9]*(带星号)将始终至少匹配空字符串(* 表示{0,},所以“零个或多个... ")。

【讨论】:

    猜你喜欢
    • 2021-08-21
    • 1970-01-01
    • 1970-01-01
    • 2013-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多