Regular expression for asp:RegularExpressionValidator with format MMddyy (leap year issue)

て烟熏妆下的殇ゞ 提交于 2019-11-26 19:09:41

OK, you asked for a regex. Here it is. I think it's immediately obvious why it's not a good idea to validate a date with a regular expression:

First, the verbose, commented version to at least make understanding this beast possible:

^       # 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}
 )
)$

Or, if you can't use verbose regexes in ASP.NET validators:

^(?:^(?:(?:(?:(?:(?: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}))$)$

These allow but do not require a leading zero in single-digit months/days. If you don't want that, replace all instances of 0? with 0.

If server side is not an option, you'll have to use JavaScript. Try the code posted and explained here. It determines that 02/29/2010 is invalid and 02/29/2008 is valid. Use a CustomValidator to call the JavaScript function when necessary.

Since you need logic to validate leap years, consider using a CustomValidator. I put this together relatively quickly, but hopefully you'll get the idea.

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;
    }
}

As bitwise says clientside JS is the way to do this not a horrible regex a la Tom's mindboggling post. I've got quite a tidy date validator on my work machine, I'll post on Monday.

If you ever get some kind of failed validation issue with your app can you imagine the nightmare of trying to de-cipher that regex?

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!