700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 【正则表达式 】java 正则表达式 校验日期格式

【正则表达式 】java 正则表达式 校验日期格式

时间:2019-08-29 22:50:39

相关推荐

【正则表达式 】java 正则表达式 校验日期格式

【正则表达式 】java 正则表达式 校验日期格式

版权声明:本文为CSDN博主「RanLZ」的原创文章,转载请附上原文出处链接及本声明。

原文链接:/RangeLZ/article/details/127109751

1 引言

我们时常会遇到,判断一个String是不是合法的日期格式。当其是一个正确的日期时,我们还需要判断其格式是否符合我们的规范,常见格式如下:

yyyyMMdd (0929)yyyy-MM-dd (-09-29)yyyy/MM/dd (/09/29)yyyy.MM.dd (.09.29)

对于这些不同的格式来说,其实我们只要确定了年月日,再根据不同的格式来微调我们的正则表达式即可。因此本篇讲解以格式yyyyMMdd为例。其他格式不再详解,其正则表达式微调即可得到,这里就不赘述了。

2 基础知识

2.1 什么是正确的日期

MSDN中定义的DateTime对象的有效范围是:0001-01-01 00:00:00到9999-12-31 23:59:59。

因此我们筛选的日期为0001010199991231(以格式yyyyMMdd为例,后文将不再强调)

其次,对于日历中大家都知道的大月小月,这里也不再赘述。

在小月中有个特殊的2月,它一个月只有28 或 29天,而其具体的天数根据是否为闰年来决定。

2.2 什么是闰年

我们通过计算方式的不同,将闰年分为普通闰年世纪闰年

普通闰年:公历年份是4的倍数,且不是100的倍数的,为闰年(如、等就是闰年)。世纪闰年:公历年份是整百数的,必须是400的倍数才是闰年(如1900年不是闰年,2000年是闰年)。

2.3 正则表达式基础

由于正则表达式的知识比较繁多,这里不做过多的介绍。只对本文将用到的表达式进行讲解。

接下来我们将这些简单的字符进行一个组合,看看你是否还能理解他们的意思呢?

简单的学会使用正则表达式了,那我们就开始正式的开始书写吧。

3 构造正则表达式

3.1 闰年的情况

为了方便后面的表示,我们将yyyy变为y1y2y3y4

3.1.1 世纪闰年的情况

世纪闰年:公历年份是整百数的,必须是400的倍数才是闰年(如1900年不是闰年,2000年是闰年)。

世纪闰年的定义我们可以知道,y3 和 y4 一定是0的,因此可得如下表格:

现在来讨论 y1 和 y2,由定义可知,我们可知 y1y2这个二位数一定是4的倍数。4的倍数的二位数一共有:

04、08、12、16、20、24、28、32、36、40、44、48、52、56、60、64、68、72、76、80、84、88、92、96、

相信大家也看出规律了,因此可得如下表格:

可以看到,此时有3种情况,这里我们用 | 将其联系起来成为一条正则表达式,如下:

((0[48]|[2468][048]|[3579][26])00)

3.1.2 普通闰年的情况

普通闰年:公历年份是4的倍数,且不是100的倍数的,为闰年(如、等就是闰年)。

因此在此我们只需要判断,y1y2y3y4是否为4的倍数即可,但这里也想上面把所有情况列出来找规律吗?这里可是4位数,情况将远远大于2位数的情况。这里我们来找找有没有什么可以减少位数的方法呢?

∵\because∵y1y2y3y4===y1y200+y3y4

∵\because∵y1y200=100∗m(m∈N)= 100 * m(m \in N)=100∗m(m∈N)

∴\therefore∴y1y2y3y4=100∗m= 100 * m=100∗m +y3y4(m∈N)(m \in N)(m∈N)

∵100=4∗25\because 100 = 4 * 25∵100=4∗25

∴100为4的倍数\therefore 100为4的倍数∴100为4的倍数

∴\therefore∴y1y200=4∗25∗m(m∈N),为4的倍数= 4 * 25 * m(m \in N),为4的倍数=4∗25∗m(m∈N),为4的倍数

所以y1y200不管y1y2为何值都为4的倍数,可得下表:

而我们可以知道,一个为4的倍数的数,只有加上一个为4的倍数,和才能为4的倍数。故我们现在只需要求y3y4为4的情况即可,我们按照之前列举的方法可得如下表:

这里我们用 | 将其联系起来成为一条正则表达式,如下:

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

3.1.3 闰年的特殊日期

我们可以知道闰年的特殊之处在于2月29日这一天是否存在,其他日子不存在闰年与平年的区别。因此我们只需要在闰年的情况下,判断2月29日这一天的日子即可,故可得以下正则表达式:

世纪闰年:(\d{2})(0[48]|[2468][048]|[13579][26])0229普通闰年:((0[48]|[2468][048]|[3579][26])00)0229

用 | 将其联系起来成为一条正则表达式,如下:

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

3.2 其他情况

现在解决了2月29日这个棘手的问题,对于其他日子,我们将不在区分闰年。看到这你是不是以为就可以直接\d{4}来表示y1y2y3y4了?

看来你忽略了一个条件,在2.2.1中我们明确了时间的范围为为0001010199991231,但当y1y2y3y4\d{4}存在0000这个情况,显然这个数据并不在我们合法的范围中。

因此我们可以得到如下的表:

用 | 将其联系起来成为一条正则表达式,如下:

(\d{3}[1-9]|\d{2}[1-9]\d|\d[1-9]\d{2}|[1-9]\d{3})

然后就是构造的正则表达式了

3.2.1 大月

首先是大月为:01,03,05,07,08,10,12。

正则表达式如下:

(0[13578]|1[02])

大月每月的日子从1日-31日均有。

正则表达式如下:

(0[1-9]|[12]\d|3[01])

故大月的正则表达式为:

((0[13578]|1[02])(0[1-9]|[12]\d|3[01]))

3.2.2 小月

首先是小月为:02,04,06,09,11。(但2月的日子和其他小月不同,这里将排除掉2月)

正则表达式如下:

(0[469]|11)

小月(不含2月)每月的日子从1日-30日均有。

正则表达式如下:

(0[1-9]|[12]\d|30)

故小月(除2月)的正则表达式为:

(0[469]|11)(0[1-9]|[12]\d|30))

3.2.3 2月

因为前面我们已经特殊表示了2月29日,所以这里我们只需要考虑2月的1日到28日,正则表达式如下:

(02(0[1-9]|[1]\d|2[0-8])

3.3 完整表达式

现在我们将全年的年月日均表达出来了,我们将其用 | 联系起来可得如下正则表达式(不包含2月29日):

((\d{3}[1-9]|\d{2}[1-9]\d|\d[1-9]\d{2}|[1-9]\d{3})(((0[13578]|1[02])(0[1-9]|[12]\d|3[01]))|((0[469]|11)(0[1-9]|[12]\d|30))|(02(0[1-9]|[1]\d|2[0-8]))))

4 总结

经过前面的努力,我们得到了如下的两个表达式:

闰年2月29日情况:(((\d{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))0229)不含2月29日情况:((\d{3}[1-9]|\d{2}[1-9]\d|\d[1-9]\d{2}|[1-9]\d{3})(((0[13578]|1[02])(0[1-9]|[12]\d|3[01]))|((0[469]|11)(0[1-9]|[12]\d|30))|(02(0[1-9]|[1]\d|2[0-8]))))

最终我们将这两个情况,用 | 联系起来,我们就得到了校验日期的正则表达式了!

((\d{3}[1-9]|\d{2}[1-9]\d|\d[1-9]\d{2}|[1-9]\d{3})(((0[13578]|1[02])(0[1-9]|[12]\d|3[01]))|((0[469]|11)(0[1-9]|[12]\d|30))|(02(0[1-9]|[1]\d|2[0-8]))))|(((\d{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))0229)

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。