本文地址:http://www.cnblogs.com/vnii/archive/2012/11/22/2782865.html
接到需求,將數據庫里面的一些標題數據中含有日期的給提取出來,利用提取的時間和當前時間來計算時間間隔,本像利用sql 的patindex等函數來提取,發現sql來寫比較繁瑣,后用正則表達式結合C#實現,本文主要記錄正則表達式部分 (必需有年,且格式順序為年月日,中間分隔符為[".","年","-","/"],月份和日可以為1月1日,01月01日)
先上表達式結果:
(?<Date>((?<!\d)((\d{2,4}(\.|年|\/|\-))((((0?[13578]|1[02])(\.|月|\/|\-))((3[01])|([12][0-9])|(0?[1-9])))|(0?2(\.|月|\/|\-)((2[0-8])|(1[0-9])|(0?[1-9])))|(((0?[469]|11)(\.|月|\/|\-))((30)|([12][0-9])|(0?[1-9]))))|((([0-9]{2})((0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))(\.|年|\/|\-))0?2(\.|月|\/|\-)29))日?(?!\d))
1.寫這個正則的目的主要是為了從數據的標題中獲取包含的日期
2.對應格式為 年月日(yyyy年MM月dd日、yyyy年M月d日、yyyy.MM.dd、yyyy.M.d、yyyy/MM/dd、yyyy/M/d、yyyy-MM-dd、yyyy-M-d) ,支持閏年(閏年參考了http://www.cnblogs.com/jay-xu33/archive/2009/01/08/1371953.html)
3.代碼中的 (?<!\d)和(?!\d)注意用法,其中 (?<!\d)為反向否定預查,(?!\d)為正向否定預查 可見 http://baike.baidu.com/view/94238.htm
4.閏年部分
( ( ([0-9]{2})((0[48]|[2468][048]|[13579][26]) //被4整除,不被100整除 | ((0[48]|[2468][048]|[3579][26])00) //被400整除 ) (\.|年|\/|\-) ) 0?2(\.|月|\/|\-)29) //2月29 02月29 //將閏年的兩個條件合並結合如下 ((([0-9]{2})((0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))(\.|年|\/|\-))0?2(\.|月|\/|\-)29)
5.非閏年部分
( ( ((0?[13578]|1[02])(\.|月|\/|\-)) //月份 1,3,5,7,8,10,12 ((3[01])|([12][0-9])|(0?[1-9])) //月份 1,3,5,7,8,10,12 對應的日期,包含31日 ) | (0?2(\.|月|\/|\-)((2[0-8])|(1[0-9])|(0?[1-9]))) //非閏年2月份 只包括28日 | ( ((0?[469]|11)(\.|月|\/|\-)) //月份 4,6,9,11 ((30)|([12][0-9])|(0?[1-9])) //月份 4,6,9,11 對應的日期,包含31日 ) ) 將大月、小月和2月合並如下: ((((0?[13578]|1[02])(\.|月|\/|\-))((3[01])|([12][0-9])|(0?[1-9])))|(0?2(\.|月|\/|\-)((2[0-8])|(1[0-9])|(0?[1-9])))|(((0?[469]|11)(\.|月|\/|\-))((30)|([12][0-9])|(0?[1-9]))))
6.合並閏年和非閏年
7.利用 (?<!\d)和(?!\d)和來判斷日期的首尾的開始和結束
憂郁的匹格 2012.11.22 發布於博客園 http://www.cnblogs.com/vnii