1. 程式人生 > >正則表示式匹配日期格式yyyy-mm-dd(支援閏年)

正則表示式匹配日期格式yyyy-mm-dd(支援閏年)

日期格式:年-月-日,即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日

當然,以上的正則表示式還能夠進一步進行優化^_^

相關推薦

表示式匹配日期格式yyyy-mm-dd支援閏年

日期格式:年-月-日,即yyyy-mm-dd,如今天的日期為2008-11-1,當然按照yyyy-mm-dd的模式就是2008-11-01。我們的表示式應該同時匹配這兩種日期——月、日為個位數的時候,前邊的‘0’可有可無。 再有的一點,估計我們匹配萬年曆的機會不是太多,一般情況下,小打小鬧,匹配個生辰八字

PHP表示式檢查日期YYYY-MM-DD格式

                         

日期格式yyyy-MM-dd hh:MM:ss的表示式

       加上引用: using System.Text.RegularExpressions;          /// <summary>         /// 檢查字串是否是日期格式,年份為2000-2039,而且沒有排除閏年         ///

Java表示式匹配日期及基本使用

廢話不多說,直接上程式碼: package top.yangxianyang.test; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.junit.Test; public

java表示式匹配日期

public static List<String> run(String text) { String dateStr = text.replaceAll("r?n", " "); List<String>

Java中用表示式判斷日期格式是否正確

/** * @Title:DateType.java * @Package:com.you.dao * @Description: * @Author: 遊海東 * @date: 2014年3月8日 下午10:54:50 * @Version V1.2.3 */ package

輸入格式: 輸入在一行中按照格式yyyy/mm/dd即“年/月/日”給出日期。注意:閏年的判別條件是該年年份能被4整除但不能被100整除、或者能被400整除。閏年的2月有29天。 輸出格式

本題要求編寫程式計算某年某月某日是該年中的第幾天。輸入格式:輸入在一行中按照格式“yyyy/mm/dd”(即“年/月/日”)給出日期。注意:閏年的判別條件是該年年份能被4整除但不能被100整除、或者能被400整除。閏年的2月有29天。輸出格式:在一行輸出日期是該年中的第幾天。

java日期格式yyyy-MM-dd HH:mm:ss該如何記憶?

寫在前面 在格式化時間的時候,總是忘記時間格式的寫法,查閱了下JDK文件總結如下。記不住就背下來吧 QAQ yyyy這個不用說,表示年,如果寫成大寫,java是不認的 IllegalArgume

python表示式匹配時間與日期

import refrom datetime import datetimetest_date = '他的生日是2016-12-12 14:34,是個可愛的小寶貝.二寶的生日是2016-12-21 11:34,好可愛的.'test_datetime = '他的生日是2016-

獲取當前的日期時間 格式yyyy-MM-dd HH:MM:SS”

div getdate pan tno class spa for etsec gets 獲取當前的日期時間 格式“yyyy-MM-dd HH:MM:SS” function getNowFormatDate() { var date = new Date();

[Swift]LeetCode10. 表示式匹配 | Regular Expression Matching

Given an input string (s) and a pattern (p), implement regular expression matching with support for '.' and '*'. '.' Matches any single cha

表示式匹配原則

基本模式匹配 一切從最基本的開始。模式,是正則表示式最基本的元素,它們是一組描述字串特徵的字元。模式可以很簡單,由普通的字串組成,也可以非常複雜,往往用特殊的字元表示一個範圍內的字元、重複出現,或表示上下文。例如: ^once 這個模式包含一個特殊的字元^,表示該模式只匹配那些以once開頭的字串。例如

表示式匹配換行符

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

PHP 表示式---匹配模式

1、PHP 正則表示式 <一>正則表示式貪婪匹配,非貪婪匹配。 預設是貪婪匹配, 例如 ①、貪婪匹配, $str = '香腸月餅'; preg_match('/(.)</td>/',$str,$rs); print_r($rs); ②、 $str = '香腸月餅'; preg_

C# -- 表示式匹配字元之含義

原文: C# -- 正則表示式匹配字元之含義 C#正則表示式匹配字元之含義 1.正則表示式的作用:用來描述字串的特徵。 2.各個匹配字元的含義: .   :表示除\n以外的單個字元 [ ]  :表示在字元陣列[]中羅列出來的字元任意取單個 |   :表示“或”的意思

劍指offer——表示式匹配遞迴呼叫

當模式中的第二個字元不是“*”時: 1、如果字串第一個字元和模式中的第一個字元相匹配,那麼字串和模式都後移一個字元,然後匹配剩餘的。 2、如果 字串第一個字元和模式中的第一個字元相不匹配,直接返回false。 而當模式中的第二個字元是“*”時: 如果字串第一個字元跟模式第一個字元

常用的表示式匹配數字

匹配特殊字元 匹配中文字元的正則表示式: [\u4e00-\u9fa5] 評註:匹配中文還真是個頭疼的事,有了這個表示式就好辦了 匹配雙位元組字元(包括漢字在內):[^\x00-\xff] 評註:可以用來計算字串的長度(一個雙位元組字元長度計2,ASCII字元計1)

SQL語句表示式 匹配(獲取) 所有表名

寫出匹配SQL語句中的所有表名,備忘記錄 折磨了好久,正則表示式如下: *\s+from\s+[\w ]*.?[\w ]*.? ?(\b\w+) ?(\b\w+) ?[\r\n\s]* 支援各種表示式 SELECT * FROM Config SELE

表示式匹配最後一部分

今天,同事問了我一個正則,最後解決了,給大家提供一下參考。用於取網址的最後一部分。本文用於講解(?= 和 ?<= 和 ?>=和 ?! 的用法) 資料如下: https://download.microsoft.com/download/5/3/8/5388ECC4-C2E2-

表示式匹配案例

import re import time import sys #先開啟1.txt檔案,讀取文字內容,然後建立一個匹配函式並呼叫(獲取文字的address) #終端輸入python3 本檔名.py 匹配內容(例:BATA100) #匹配具體內容 def reg(data,port): patte