本文地址: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