日期正则表达式(转)

简单正则 : \d{4}-\d{2}-\d{2}
实际情况却简单,,要考虑,有效性和闰年等问题.....

对于日期有效范围应用场景会有所MSDN定义DateTime对象有效范围:0001-01-01 00:00:009999-12-31 23:59:59

UNIX时间戳0按照ISO 8601规范 :1970-01-01T00:00:00Z

先考虑与年份无关前三条规则年份写作

(?!0000)[0-9]{4}

下面仅考虑月和日正则

1. 包括平年所有年份月份都包含1-28日

(0[1-9]|1[0-2])-(0[1-9]|1[0-9]|2[0-8])

2. 包括平年所有年份除2月外都包含29和30日

(0[13-9]|1[0-2])-(29|30)

3. 包括平年所有年份1、3、5、7、8、10、12月都包含31日

(0[13578]|1[02])-31)

合起来闰年2月29日外所有日期

(?!0000)[0-9]{4}-((0[1-9]|1[0-2])-(0[1-9]|1[0-9]|2[0-8])|(0[13-9]|1[0-2])-(29|30)|(0[13578]|1[02])-31)

接下来考虑闰年实现

1 : 四年
([0-9]{2}(0[48]|[2468][048]|[13579][26])

2 : 百年四百年再闰
(0[48]|[2468][048]|[13579][26])00

3 : 合起来所有闰年2月29日
([0-9]{2}(0[48]|[2468][048]|[13579][26])|(0[48]|[2468][048]|[13579][26])00)-02-29)

四条规则都已实现且互相间没有影响合起来所有符合DateTime范围日期正则

^((?!0000)[0-9]{4}-((0[1-9]|1[0-2])-(0[1-9]|1[0-9]|2[0-8])|(0[13-9]|1[0-2])-(29|30)|(0[13578]|1[02])-31)|([0-9]{2}(0[48]|[2468][048]|[13579][26])|(0[48]|[2468][048]|[13579][26])00)-02-29)$

考虑正则表达式仅仅用作验证捕获组没有意义只会占用资源影响匹配效率使用非捕获组来进行优化

^(?:(?!0000)[0-9]{4}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)-02-29)$

posted on 2014-03-12 12:29  soryou  阅读(118)  评论(0)    收藏  举报