java正則表達式校驗日期格式實例代碼
1 引言
我們時常會遇到,判斷一個String是不是合法的日期格式。當其是一個正確的日期時,我們還需要判斷其格式是否符合我們的規(guī)范,常見格式如下:
- yyyyMMdd (20220929)
- yyyy-MM-dd (2022-09-29)
- yyyy/MM/dd (2022/09/29)
- yyyy.MM.dd (2022.09.29)
對于這些不同的格式來說,其實我們只要確定了年月日,再根據不同的格式來微調我們的正則表達式即可。因此本篇講解以格式 yyyyMMdd
為例。其他格式不再詳解,其正則表達式微調即可得到,這里就不贅述了。
2 基礎知識
2.1 什么是正確的日期
MSDN中定義的DateTime對象的有效范圍是:0001-01-01 00:00:00到9999-12-31 23:59:59。
- 因此我們篩選的日期為
00010101
到99991231
(以格式yyyyMMdd
為例,后文將不再強調)
其次,對于日歷中大家都知道的 大月 和 小月,這里也不再贅述。
在小月中有個特殊的 2月
,它一個月只有28 或 29天,而其具體的天數(shù)根據是否為 閏年 來決定。
2.2 什么是閏年
我們通過計算方式的不同,將閏年分為 普通閏年 和 世紀閏年。
- 普通閏年:公歷年份是4的倍數(shù),且不是100的倍數(shù)的,為閏年(如2004年、2020年等就是閏年)。
- 世紀閏年:公歷年份是整百數(shù)的,必須是400的倍數(shù)才是閏年(如1900年不是閏年,2000年是閏年)。
2.3 正則表達式基礎
由于正則表達式的知識比較繁多,這里不做過多的介紹。只對本文將用到的表達式進行講解。
字符 | 描述 |
---|---|
| | 指明兩項之間的一個選擇,意為或 。 |
\d | 匹配一個數(shù)字字符。等價于 [0-9]。 |
{n} | n 是一個非負整數(shù)。匹配確定的 n 次。 |
[1-9] | [1-9] 表示一個區(qū)間,匹配1-9的數(shù)字 |
[ABC] | 匹配 […] 中的所有字符,例如 [358] 匹配數(shù)字 3、5、8 |
接下來我們將這些簡單的字符進行一個組合,看看你是否還能理解他們的意思呢?
正則表達式 | 描述 | 舉例文本 | 錯誤文本 |
---|---|---|---|
\d{3} | 3個數(shù)字都是0-9的間的數(shù)字 | 237、832、129 | a37、ufo |
\d{3}[1-9] | 前3個數(shù)字都是0-9的間的數(shù)字,第四個數(shù)字是1-9直接的數(shù)字 | 2372、4041、9001 | 8720、2020 |
[7-9]|[523] | 該數(shù)字要么是7-9之間的一個數(shù),要么是2,3,5其中的一個數(shù)字 | 7、5、2 | 1、4、6 |
簡單的學會使用正則表達式了,那我們就開始正式的開始書寫吧。
3 構造正則表達式
3.1 閏年的情況
為了方便后面的表示,我們將 yyyy 變?yōu)?y1y2y3y4
3.1.1 世紀閏年的情況
- 世紀閏年:公歷年份是整百數(shù)的,必須是400的倍數(shù)才是閏年(如1900年不是閏年,2000年是閏年)。
由 世紀閏年 的定義我們可以知道,y3 和 y4 一定是0的,因此可得如下表格:
y1 | y2 | y3 | y4 |
---|---|---|---|
待定 | 待定 | 0 | 0 |
現(xiàn)在來討論 y1 和 y2,由定義可知,我們可知 y1y2這個二位數(shù)一定是4的倍數(shù)。4的倍數(shù)的二位數(shù)一共有:
- 04、08、12、16、20、
- 24、28、32、36、40、
- 44、48、52、56、60、
- 64、68、72、76、80、
- 84、88、92、96、
相信大家也看出規(guī)律了,因此可得如下表格:
y1 | y2 | y1y2 | y3 | y4 |
---|---|---|---|---|
0 | [48] | 0[48] | 0 | 0 |
[2468] | [48] | [2468][048] | 0 | 0 |
[3579] | [48] | [3579][26] | 0 | 0 |
可以看到,此時有3種情況,這里我們用 | 將其聯(lián)系起來成為一條正則表達式,如下:
((0[48]|[2468][048]|[3579][26])00)
3.1.2 普通閏年的情況
- 普通閏年:公歷年份是4的倍數(shù),且不是100的倍數(shù)的,為閏年(如2004年、2020年等就是閏年)。
因此在此我們只需要判斷,y1y2y3y4 是否為4的倍數(shù)即可,但這里也想上面把所有情況列出來找規(guī)律嗎?這里可是4位數(shù),情況將遠遠大于2位數(shù)的情況。這里我們來找找有沒有什么可以減少位數(shù)的方法呢?
所以 y1y200 不管 y1y2 為何值都為4的倍數(shù),可得下表:
y1 | y2 | y1y2 | y3 | y4 |
---|---|---|---|---|
\d | \d | \d{2} | 待定 | 待定 |
而我們可以知道,一個為4的倍數(shù)的數(shù),只有加上一個為4的倍數(shù),和才能為4的倍數(shù)。故我們現(xiàn)在只需要求 y3y4 為4的情況即可,我們按照之前列舉的方法可得如下表:
y1 | y2 | y1y2 | y3 | y4 |
---|---|---|---|---|
\d | \d | \d{2} | 0 | [48] |
\d | \d | \d{2} | [2468] | [48] |
\d | \d | \d{2} | [13579] | [26] |
這里我們用 | 將其聯(lián)系起來成為一條正則表達式,如下:
(\d{2})(0[48]|[2468][048]|[13579][26])
3.1.3 閏年的特殊日期
我們可以知道閏年的特殊之處在于2月29日
這一天是否存在,其他日子不存在閏年與平年的區(qū)別。因此我們只需要在閏年的情況下,判斷2月29日這一天的日子即可,故可得以下正則表達式:
世紀閏年:(\d{2})(0[48]|[2468][048]|[13579][26])0229 普通閏年:((0[48]|[2468][048]|[3579][26])00)0229
用 | 將其聯(lián)系起來成為一條正則表達式,如下:
(((\d{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))0229)
3.2 其他情況
現(xiàn)在解決了 2月29日
這個棘手的問題,對于其他日子,我們將不在區(qū)分閏年??吹竭@你是不是以為就可以直接 \d{4}
來表示y1y2y3y4 了?
看來你忽略了一個條件,在 2.2.1
中我們明確了時間的范圍為為 00010101
到 99991231
,但當 y1y2y3y4 為 \d{4}
存在 0000
這個情況,顯然這個數(shù)據并不在我們合法的范圍中。
因此我們可以得到如下的表:
y1 | y2 | y3 | y4 |
---|---|---|---|
\d | \d | \d | [1-9] |
\d | \d | [1-9] | \d |
\d | [1-9] | \d | \d |
[1-9] | \d | \d | \d |
用 | 將其聯(lián)系起來成為一條正則表達式,如下:
(\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 完整表達式
現(xiàn)在我們將全年的年月日均表達出來了,我們將其用 | 聯(lián)系起來可得如下正則表達式(不包含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]))))
最終我們將這兩個情況,用 | 聯(lián)系起來,我們就得到了校驗日期的正則表達式了!
((\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)
到此這篇關于java正則表達式校驗日期格式的文章就介紹到這了,更多相關java正則校驗日期格式內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
SpringBoot嵌入式Servlet容器與定制化組件超詳細講解
這篇文章主要介紹了SpringBoot嵌入式Servlet容器與定制化組件的使用介紹,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習吧2022-10-10- 這篇文章將大概用代碼案例簡單總結一下?Collection?接口中的一些方法,我們會以他的實現(xiàn)類?Arraylist?為例創(chuàng)建對象??煲黄饋砜纯窗?/div> 2022-12-12
Java基于字符流形式讀寫數(shù)據的兩種實現(xiàn)方法示例
這篇文章主要介紹了Java基于字符流形式讀寫數(shù)據的兩種實現(xiàn)方法示,結合實例形式分析了java逐個字符讀寫及使用緩沖區(qū)進行讀寫操作的具體實現(xiàn)技巧,需要的朋友可以參考下2018-01-01最新評論