修正正则匹配日期---基于网络未知大神的正则

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了修正正则匹配日期---基于网络未知大神的正则相关的知识,希望对你有一定的参考价值。

今天工作时需要用到日期格式检验,于是发现未知的大神贡献的一套正则表达式【1】,看起来很复杂;

但是经过测试发现有些问题:

((\\d{2}(([02468][048])|([13579][26]))[-/\\s]?((((0?[13578]
)|(1[02]))[-/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[4
69])|(11))[-/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[-/
\\s]?((0?[1-9])|([1-2][0-9])))))|(\\d{2}(([02468][1235679])|([1
3579][01345789]))[-/\\s]?((((0?[13578])|(1[02]))[-/\\s]?((
0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[-/\\s]?((
0?[1-9])|([1-2][0-9])|(30)))|(0?2[-/\\s]?((0?[1-9])|(1[0-9]
)|(2[0-8]))))))

经测试发现是存在一些问题的,如 1980-2-29只能匹配到1980-2-2,2100-2-29(非闰年)是会进入第一个闰年匹配的,这样就会出现闰年匹配和日期匹配不正确的情况。

技术分享

在此基础上,我做了一些修改,在此贴出:

(((((([2468][048])|([13579][26]))00)|(\\d{2}((([2468][048])|([02468][48]))|([13579][26]))))
[-/\\s]?((((1[02])|(0?[13578]))[-/\\s]?(([1-2][0-9])|(3[01])|(0?[1-9])))|(((11)|(0?[469]))
[-/\\s]?(([1-2][0-9])|(30)|(0?[1-9])))|(0?2[-/\\s]?(([1-2][0-9]))|(0?[1-9]))))
|((((([2468][1235679])|([13579][01345789]))00)|(\\d{2}(([02468][1235679])|([13579][01345789]))))
[-/\\s]?((((1[02])|(0?[13578]))[-/\\s]?(([1-2][0-9])|(3[01])|(0?[1-9])))|(((0?[469])|(11))
[-/\\s]?(([1-2][0-9])|(30)|(0?[1-9])))|(0?2[-/\\s]?((1[0-9])|(2[0-8]))|(0?[1-9])))))

下面对改动的正则分块做一下说明:

1.匹配闰年:

(((([2468][048])|([13579][26]))00)|(\\d{2}((([2468][048])|([02468][48]))|([13579][26]))))

1.1 匹配可被400整除的年份

((([2468][048])|([13579][26]))00)

1.2 匹配可被4整除但不能被100整除的年份

(\\d{2}((([2468][048])|([02468][48]))|([13579][26])))

1.3 注:经查阅 4的倍数有以下特征:(1):十位数为偶数时且个位是4的倍数的(含0),十位数为奇数且个位数为偶数且个位数字不是4的倍数; (2)十位和个位可被4整除则此数字即可被4整除;【2】

 

2.匹配月日;需注意2月分的29号 和区别大小月份,1 3 5 7 8 10 12 这些是大月

((((1[02])|(0?[13578]))[-/\\s]?(([1-2][0-9])|(3[01])|(0?[1-9])))|(((11)|(0?[469]))[-/\\s]?(([1-2][0-9])|(30)|(0?[1-9])))|(0?2[-/\\s]?(([1-2][0-9]))|(0?[1-9])))

2.1 解决02-29只匹配到02-2的问题

改动前:(0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))
改动后:([1-2][0-9])|(3[01])|(0?[1-9])))|(((11)|(0?[469]))

由于未知的作者将最初将补零的验证置前,且0为匹配1次或0次,则匹配到[1-9]后不再进行 ‘或’ 后的匹配;

 

3. 匹配平年

(((([2468][1235679])|([13579][01345789]))00)|(\\d{2}(([02468][1235679])|([13579][01345789]))))

3.1 匹配不能被4整除,但可以被100整除的年份;

((([2468][1235679])|([13579][01345789]))00)

3.2 匹配既不能被4整除,又不能被100整除的年份;

(\\d{2}(([02468][1235679])|([13579][01345789])))

 

平年的月与闰年月只需注意区分2月即可

 

经测试通过验证;

 

如有不对,敬请指教

 

参考:

【1】http://www.php230.com/1409454901.html 

【2】https://www.zybang.com/question/61a275532cdfa6fe88b1360ed4ec6182.html

 

以上是关于修正正则匹配日期---基于网络未知大神的正则的主要内容,如果未能解决你的问题,请参考以下文章

正则表达式中常用的模式修正符有igmsxe详解

正则表达式中模式修正符作用详解(igmsxe)

php正则表达式问题

python正则表达式匹配中文日期时间

python正则表达式匹配中文日期时间

正则 模式修正符