完美的日期验证正则表达式

来源:互联网 发布:java点击量统计代码 编辑:程序博客网 时间:2024/05/04 19:54

比较完美的日期验证(格式和日期数据有效性)

string pattern="^(((([0-9]{2}(([2468][048])|([02468][48])|([13579][26])))|((([02468][048])|([13579][26]))(00)))(-)(2|02)(-)(([0]?[1-9])|([1-2][0-9])))|((([0-9]{2}([02468][1235679])|([13579][01345789]))|((([02468][1235679])|([13579][01345789]))(00)))(-)(2|02)(-)(([0]?[1-9])|([1][0-9])|([2][0-8])))|(([0-9]{4})(-)(((([0]?(1|3|5|7|8))|(10|12))(-)(([0]?[1-9])|([1-2][0-9])|30|31))|(((([0]?(4|6|9))|11))(-)(([0]?[1-9])|([1-2][0-9])|30)))))$";

 

Regex re = new Regex(pattern);
                if (!re.IsMatch(strInput))
                {
                    MessageBox.Show("日期格式不正确");
                    return;
                }

---------------------------------------------------------------------------------------------------------

首先需要验证年份,显然,年份范围为 0001 - 9999,匹配YYYY的正则表达式为:

 

我们知道,每 400 年会有 97 个闰年(参见高中《地理》课本),完整的瑞年判断是这样的:
  瑞年的年份
  1) 若是整百年,能被 400 整除
  否则
  2) 能被 4 整除

      确实是能被3200整除的也不是闰年

下面给出代码,主要是为 String 原型添加 isDate 方法:

<script type="text/javascript">
// 分隔符
Separator = {
    ANY: ".",
    DASH: "-",
    DOT: "//.",
    SLASH: "/"
};
String.prototype.isDate = function(sep) {
    var reStr = "^(((([0-9]{2}(([2468][048])|([02468][48])|([13579][26])))|((([02468][048])|([13579][26]))(00)))(-)(2|02)(-)(([0]?[1-9])|([1-2][0-9])))|((([0-9]{2}([02468][1235679])|([13579][01345789]))|((([02468][1235679])|([13579][01345789]))(00)))(-)(2|02)(-)(([0]?[1-9])|([1][0-9])|([2][0-8])))|(([0-9]{4})(-)(((([0]?(1|3|5|7|8))|(10|12))(-)(([0]?[1-9])|([1-2][0-9])|30|31))|(((([0]?(4|6))|11))(-)(([0]?[1-9])|([1-2][0-9])|30)))))$";
    if(typeof(sep) == "string")
        reStr = reStr.replace(//(-/)/g, "(" + sep + ")");
    var re = new RegExp(reStr, "g");
    return re.test(this);
};
alert("2100-2-29".isDate());   
alert("2000/02/29".isDate(Separator.SLASH));
alert("2007/5/22".isDate(Separator.SLASH));
alert("2007-09-31".isDate());
alert("2004.02.29".isDate(Separator.DOT));
alert("2008-02-29".isDate());
// 结果
// false
// true
// true
// false
// true
// true
</script>

上面的正则表达式可以看成是由三个正则表达式拼接而成,瑞年二月判断、非闰年二月判断、其它月份判断。

 

 

 在线验证工具: http://www.rubular.com/

[0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3}
其中 [0-9] 也可以表示为 /d,但 /d 不如 [0-9] 直观,因此下面我将一直采用 [0-9]

用正则表达式验证日期的难点有二:一是大小月份的天数不同,二是闰年的考虑。
对于第一个难点,我们首先不考虑闰年,假设2月份都是28天,这样,月份和日期可以分成三种情况:

1、月份为 1, 3, 5, 7, 8, 10, 12,天数范围为 01 - 31,匹配MM-DD的正则表达式为:
(0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01])
2、月份为 4, 6, 9, 11,天数范围为 01-30,匹配MM-DD的正则表达式为:
(0[469]|11)-(0[1-9]|[12][0-9]|30)
3、月份为 2,考虑平年情况,匹配MM-DD的正则表达式为:
02-(0[1-9]|[1][0-9]|2[0-8])
根据上面的成果,我们可以得到匹配平年日期格式为YYYY-MM-DD的正则表达式:

([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8])))

接着我们来解决第二个难点:闰年的考虑。根据闰年的定义,我们可以将闰年分为两类:

1、能被4整除但不能被100整除的年份。寻找后两位的变化规律,可以很快得到下面的正则匹配:
([0-9]{2})(0[48]|[2468][048]|[13579][26])
2、能被400整除的年份。能被400整除的数肯定能被100整除,因此后两位肯定是00,我们只要保证前两位能被4整除即可,相应的正则表达式为:

(0[48]|[2468][048]|[3579][26])00

原创粉丝点击