使用格式为MMddyy(闰年问题)的asp:RegularExpressionValidator的正则表达式

3
我们需要帮助编写正则表达式,以便与ASP.NET asp:RegularExpressionValidator一起使用,验证MMDDYY格式的日期。我们面临的问题是闰年。问题在于是否可以通过正则表达式验证它仅接受有效的闰年日期,例如02/29/2008是一个有效的日期,但02/29/2010不是一个有效的日期。
有没有适用于"asp:RegularExpressionValidator"的正则表达式?

是mmddyy还是mm/dd/yy或mm/dd/yyyy?还有其他要求吗?01/01/1792有效吗?9/9/99或09/09/9999呢?如果是mmddyy,1900年代和2000年代之间的分界线在哪里? - Tim Pietzcker
@Tim:日期格式是月/日/年。关于有效性,我认为我们还没有任何具体要求。没有截止日期。我不认为我们需要这么详细 :(. 难道我们应该吗? - Malik
4个回答

15

好的,你要求一个正则表达式。这里是它。我认为立即显而易见的原因是使用正则表达式验证日期不是一个好主意:

首先,这是冗长的、带注释的版本,至少让理解这个怪物变得可能:

^       # start of string
(?:     # either match...
 (?:
  (?:   # 31st day of all allowed months
   (?:(?:0?[13578]|1[02])/31)
   |    # or
   (?:(?:0?[13-9]|1[0-2])/(?:29|30))
  )     # 29th/30th day of any month except February
  /     # plus any year since 1600
  (?:1[6-9]|[2-9]\d)
  \d{2}
 )
|       # or
 (?:    # match Feb 29th
  0?2/29/
  (?:   # in all leap years since 1600
   (?:
    (?: # century
     1[6-9]|[2-9]\d
    )
    (?: # two-digit years divisible by four, not ending in 00
     0[48]
     |
     [2468][048]
     |
     [13579][26]
    )
    |
    (?: # all the leap years ending in 00
     (?:16|[2468][048]|[3579][26])
    00
    )
   )
  )
 )
|       # or
 (?:    # (for any month)
  (?:0?[1-9])
  |
  (?:1[0-2])
 )
 /
 (?:    # match the 1st-28th day
  0?[1-9]|1\d|2[0-8]
 )
 /
 (?:
  (?:1[6-9]|[2-9]\d)\d{2}
 )
)$

或者,如果您不能在ASP.NET验证器中使用冗长的正则表达式:

^(?:^(?:(?:(?:(?:(?:0?[13578]|1[02])/31)|(?:(?:0?[13-9]|1[0-2])/(?:29|30)))/(?:1[6-9]|[2-9]\d)\d{2})|(?:0?2/29/(?:(?:(?:1[6-9]|[2-9]\d)(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))|(?:(?:0?[1-9])|(?:1[0-2]))/(?:0?[1-9]|1\d|2[0-8])/(?:(?:1[6-9]|[2-9]\d)\d{2}))$)$

这个允许但不强制在单个数字的月份/日期前加0。如果您不想这样,可以将所有的0?替换为0


我重新修改了一个以前从regexlib.com找到的旧代码。我绝对不会自己写出那样的东西 :) 是的,它确实有效,至少在我的机器上(商标)。 - Tim Pietzcker
@TimPietzcker...更不用说注释了! - wwaawaw
@adlwalrus:几乎所有较新的编程语言(Perl、PHP、Python、Java、Ruby、.NET、JGSoft等)都支持,唯一的例外是JavaScript。 - Tim Pietzcker
确实值得注意,不幸的是!那么,如何获得实际空格呢?\s - wwaawaw
1
@adlwalrus:\s也匹配其他空格,但在详细模式下,[ ]\(不确定反斜杠后面的空格是否会正确显示)也可以使用。 - Tim Pietzcker
显示剩余5条评论

2
如果服务器端不可用,您需要使用JavaScript。尝试在此处发布并解释的代码here。它确定02/29/2010无效,而02/29/2008有效。使用CustomValidator在必要时调用JavaScript函数。

1

由于需要逻辑来验证闰年,考虑使用CustomValidator。我相对快速地组合了这个代码,但希望您能理解。

protected void dateFormatValidator_ServerValidate(object source, ServerValidateEventArgs args)
{
    if (args.Value.Length == 6)
    {
        var month = args.Value.Substring(0, 2);
        var day = args.Value.Substring(2, 2);
        var year = args.Value.Substring(4, 2);

        DateTime dummyValue;
        args.IsValid = DateTime.TryParse(month + "/" + day + "/" + year, out dummyValue);
    }
    else
    {
        args.IsValid = false;
    }
}

非常感谢您的回复,但服务器端不是一个选项 :( - Malik

0

正如 bitwise 所说,客户端 JS 是实现这一点的方法,而不是像 Tom 的令人费解的帖子中那样使用可怕的正则表达式。我在我的工作机器上有一个相当整洁的日期验证器,我将在周一发布。

如果您的应用程序出现某种验证失败问题,您能想象尝试解密该正则表达式的噩梦吗?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接