((((19|20)\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\d|3[01]))|(((19|20)\d{2})-(0?[469]|11)-(0?[1-9]|[12]\d|30))|(((19|20)\d{2})-0?2-(0?[1-9]|1\d|2[0-8])))
@H_403_3@ @H_403_3@到了这一步,我们要开始考虑闰年的2月了,我们都知道闰年的2月有29天,但到底什么才是闰年呢?? @H_403_3@我们先花点时间列举出1900-2099之间,那些年份是闰年吧1904,1908,1912,1916,1920,1924,1928,1932,1936,1940,
1944,1948,1952,1956,1960,1964,1968,1972,1976,1980,
1984,1988,1992,1996,2000,2004,2008,2012,2016,2020,
2024,2028,2032,2036,2040,2044,2048,2052,2056,2060,
2064,2068,2072,2076,2080,2084,2088,2092,2096
@H_403_3@ @H_403_3@闰年:能够被4整除,若是整百年还必须被400整除,如1900是整百年但不能被400整除所以不是闰年,而2000年是闰年。 @H_403_3@ @H_403_3@或许我们都知道闰年该怎么算,但是正则表达式不知道,正则表达式内部是没有计算能力的,我们所能做的就是替它找出一个能够在有限次内列举出所有可能的解决方案——所以,以上我列举出所有的闰年并不是吃饱了撑着,而是为了替表达式找出规律…… @H_403_3@ @H_403_3@认真分析以上闰年之后,很容易发现: @H_403_3@1. 个位数必是偶数 @H_403_3@2. 十位数为奇数时,个位数只有两种可能:2和6 @H_403_3@3. 十位数为偶数(除0外)时,个位数有三种可能:0、4、8 @H_403_3@4. 十位数为0时,个位数为4和8,2000年特殊处理 @H_403_3@ @H_403_3@所以,匹配闰年年份如下:(((19|20)([13579][26]|[2468][048]|0[48]))|(2000)) @H_403_3@所以,闰年2月分的匹配模式为(((19|20)([13579][26]|[2468][048]|0[48]))|(2000))-0?2-(0?[1-9]|[12]\d) @H_403_3@ @H_403_3@综合前面的所有模式,即可得出匹配日期的正则表达式了((((19|20)\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\d|3[01]))|(((19|20)\d{2})-(0?[469]|11)-(0?[1-9]|[12]\d|30))|(((19|20)\d{2})-0?2-(0?[1-9]|1\d|2[0-8]))|((((19|20)([13579][26]|[2468][048]|0[48]))|(2000))-0?2-(0?[1-9]|[12]\d)))$
@H_403_3@ @H_403_3@以上表达式并不是最优的,至少以下的方式会比较优良:((((19|20)\d{2})-(0?(1|[3-9])|1[012])-(0?[1-9]|[12]\d|30))|(((19|20)\d{2})-(0?[13578]|1[02])-31)|(((19|20)\d{2})-0?2-(0?[1-9]|1\d|2[0-8]))|((((19|20)([13579][26]|[2468][048]|0[48]))|(2000))-0?2-29))$
@H_403_3@该表达式的匹配规则(按以下序号为顺序): @H_403_3@1.匹配除了2月份之外的1-30日 @H_403_3@2.若1无法匹配,则匹配1,3,5,7,8,10,12月份的31日 @H_403_3@3.若2无法匹配,则匹配2月份的1-28日 @H_403_3@4.若以上都无法匹配,那只可能剩下一天,那就是闰年2月份的最后一天2月29日当然,以上的正则表达式还能够进一步进行优化^_^