網站首頁 編程語言 正文
日期格式:年-月-日,即yyyy-mm-dd,如今天的日期為2008-11-1,當然按照yyyy-mm-dd的模式就是2008-11-01。我們的表達式應該同時匹配這兩種日期——月、日為個位數的時候,前邊的‘0’可有可無。
?
再有的一點,估計我們匹配萬年歷的機會不是太多,一般情況下,小打小鬧,匹配個生辰八字,起始、終止日期就夠了,于是我的表達式只匹配1900-2099——估計就我一般年齡的人是很難超越這兩個年份的吧……
?
廢話少說,開始寫表達式吧。
?
首先當然是年份了——((19|20)\d{2})。(這里用了Perl的寫法,由于Javascript沿用了此法,而且這種方法確實很簡潔,所以我個人非常喜歡。)
?
匹配年份是整個表達式中最簡單的部分,以下建立月和日的表達式可能出現多種情況,我只能在整個表達式中建立多種模式以供匹配的時候選擇,在這些模式中,年份的部分基本上是一樣的(除了閏年)。
?
小學生都知道的一件事:一年的12個月里,1、3、5、7、8、10、12月份中每月有31天,4、6、9、11月份中每月有30天,而2月最特殊,2月份只有28天而且閏年的時候是29天——對于閏年,我們等處理完一般情況再考慮特殊處理。
?
31天的月份——(0?[13578]|1[02])。
日期——(0?[1-9]|[12]\d|3[01])。
1. 綜上,匹配31天的月份模式為:/(年)-(月)-(日)/,即((19|20)\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\d|3[01])
?
30天的月份——(0?[469]|11)。
日期——(0?[1-9]|[12]\d|30)。
2. 綜上,匹配30天的月份模式為:/(年)-(月)-(日)/,即((19|20)\d{2})-(0?[469]|11)-(0?[1-9]|[12]\d|30)
?
以下匹配一般年份的2月,即28天的2月。
月份——0?2
日期——(0?[1-9]|1\d|2[0-8])
3. 綜上,匹配28天的2月模式為:/(年)-(月)-(日)/,即((19|20)\d{2})-0?2-(0?[1-9]|1\d|2[0-8])
?
綜合1、2、3,可建立匹配除了閏年之外的日期即——
/((31天的月份)|(30天的月份)|(28天的2月))/,即——
((((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])))
?
到了這一步,我們要開始考慮閏年的2月了,我們都知道閏年的2月有29天,但到底什么才是閏年呢??
我們先花點時間列舉出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
?
閏年:能夠被4整除,若是整百年還必須被400整除,如1900是整百年但不能被400整除所以不是閏年,而2000年是閏年。
?
或許我們都知道閏年該怎么算,但是正則表達式不知道,正則表達式內部是沒有計算能力的,我們所能做的就是替它找出一個能夠在有限次內列舉出所有可能的解決方案——所以,以上我列舉出所有的閏年并不是吃飽了撐著,而是為了替表達式找出規律……
?
認真分析以上閏年之后,很容易發現:
1. 個位數必是偶數
2. 十位數為奇數時,個位數只有兩種可能:2和6
3. 十位數為偶數(除0外)時,個位數有三種可能:0、4、8
4. 十位數為0時,個位數為4和8,2000年特殊處理
?
所以,匹配閏年年份如下:(((19|20)([13579][26]|[2468][048]|0[48]))|(2000))
所以,閏年2月分的匹配模式為(((19|20)([13579][26]|[2468][048]|0[48]))|(2000))-0?2-(0?[1-9]|[12]\d)
?
綜合前面的所有模式,即可得出匹配日期的正則表達式了
((((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)))$
?
以上表達式并不是最優的,至少以下的方式會比較優良:
((((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))$
該表達式的匹配規則(按以下序號為順序):
1.匹配除了2月份之外的1-30日
2.若1無法匹配,則匹配1,3,5,7,8,10,12月份的31日
3.若2無法匹配,則匹配2月份的1-28日
4.若以上都無法匹配,那只可能剩下一天,那就是閏年2月份的最后一天2月29日
當然,以上的正則表達式還能夠進一步進行優化^_^
原文鏈接:https://blog.csdn.net/u012861467/article/details/50119205
- 上一篇:標準時間格式轉換(正則寫法)
- 下一篇:C++ 獲取當前時間毫秒數
相關推薦
- 2022-07-21 TensorRT之mmdeploy使用
- 2023-05-06 docker?search命令的具體使用_docker
- 2022-05-21 k8s入門集群組件介紹及概念理解_服務器其它
- 2022-05-18 Matlab實現多子圖同步調整視角_C 語言
- 2022-02-11 tomcat?logs?目錄下各日志文件的解析(小結)_Tomcat
- 2022-09-30 ASP.NET?MVC為用戶創建專屬文件夾_實用技巧
- 2022-09-26 ASP.NET?Core?6最小API中使用日志和DI示例詳解_ASP.NET
- 2023-11-12 Check failed: top_shape[j] == bottom[i]->shape(j)
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支