javascript 使用正则表达式验证使用 DD-Mon-YYYY 格式的日期

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18659614/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 12:47:39  来源:igfitidea点击:

Using regexp to validate a date using DD-Mon-YYYY format

javascriptregexdate

提问by Jason Taylor

Hello I am trying to validate a date in the format: 03-Mar-2011 or 12-Dec-2007. I currently have a regexp that fails on the 3 character Month. I probably just need to tweak that to get it to work properly.

您好,我正在尝试以以下格式验证日期:2011 年 3 月 3 日或 2007 年 12 月 12 日。我目前有一个在 3 个字符月份失败的正则表达式。我可能只需要调整它以使其正常工作。

    //function isDate(txtDate) {
    function isDate(sender, args) {
        var currVal = document.getElementById('<%=txtChange_Date.ClientID%>').value;

            if (currVal == '')
                return false;

            //Declare Regex  
            var rxDatePattern = /^(\d{1,2})(\/|-)[a-zA-Z]{3}(\/|-)(\d{4})$/;

            var dtArray = currVal.match(rxDatePattern); // is format OK?

            if (dtArray == null)
                return false;

            //formerly //Checks for dd/mm/yyyy format.
            //Checks for dd-MMM-yyyy format.
            var dtDay = dtArray[1];
            var dtMonth = dtArray[3];
            var dtYear = dtArray[4];

            switch(dtMonth)
            {
                case 'Jan':
                    dtMonth = '01';
                    break;
                case 'Feb':
                    dtMonth = '02';
                    break;
                case 'Mar':
                    dtMonth = '03';
                    break;
                case 'Apr':
                    dtMonth = '04';
                    break;
                case 'May':
                    dtMonth = '05';
                    break;
                case 'Jun':
                    dtMonth = '06';
                    break;
                case 'Jul':
                    dtMonth = '07';
                    break;
                case 'Aug':
                    dtMonth = '08';
                    break;
                case 'Sep':
                    dtMonth = '09';
                    break;
                case 'Oct':
                    dtMonth = '10';
                    break;
                case 'Nov':
                    dtMonth = '11';
                    break;
                case 'Dec':
                    dtMonth = '12';
                    break;
            }


if (dtMonth < 1 || dtMonth > 12)
                return false;
else if (dtDay < 1 || dtDay > 31)
                return false;
else if ((dtMonth == 4 || dtMonth == 6 || dtMonth == 9 || dtMonth == 11) && dtDay == 31)
                return false;
else if (dtMonth == 2) {
            var isleap = (dtYear % 4 == 0 && (dtYear % 100 != 0 || dtYear % 400 == 0));
                if (dtDay > 29 || (dtDay == 29 && !isleap))
                    return false;
            }

            return true;
        }

回答by Daniel Gimenez

There were a few problems with your code, but your regular expression was fine except that month wasn't being grouped.

您的代码存在一些问题,但是您的正则表达式很好,只是那个月没有被分组。

Other Changes

其他变化

  • The switchthat converts the month needed to have dtMonthconverted to lower case and the case statements needed to match the case.
  • I explicitly converted the date parts to integers with parseInt. I don't know if it was an issue with dtDayor dtYear, but it was causing an issue with dtMonth.
  • With the parseIntchange I added a not a number check and dtMonth.
  • I also moved the validator out of the event handler. Just a good practice to follow if the validation isn't trivial.
  • switch该转换一个月需要有dtMonth转换成小写字母和大小写相匹配所需的case语句。
  • 我显式地将日期部分转换为整数parseInt。我不知道这是否是dtDay或的问题dtYear,但它导致了dtMonth.
  • 随着parseInt更改,我添加了一个非数字检查和dtMonth.
  • 我还将验证器移出了事件处理程序。如果验证不是微不足道的,那么这是一个很好的做法。

Code

代码

function isDate(currVal) {
    if (currVal == '') return false;

    //Declare Regex  
    var rxDatePattern = /^(\d{1,2})(\/|-)([a-zA-Z]{3})(\/|-)(\d{4})$/;

    var dtArray = currVal.match(rxDatePattern); // is format OK?

    if (dtArray == null) return false;

    var dtDay = parseInt(dtArray[1]);
    var dtMonth = dtArray[3];
    var dtYear = parseInt(dtArray[4]);

    // need to change to lowerCase because switch is
    // case sensitive
    switch (dtMonth.toLowerCase()) {
        case 'jan':
            dtMonth = '01';
            break;
        case 'feb':
            dtMonth = '02';
            break;
        case 'mar':
            dtMonth = '03';
            break;
        case 'apr':
            dtMonth = '04';
            break;
        case 'may':
            dtMonth = '05';
            break;
        case 'jun':
            dtMonth = '06';
            break;
        case 'jul':
            dtMonth = '07';
            break;
        case 'aug':
            dtMonth = '08';
            break;
        case 'sep':
            dtMonth = '09';
            break;
        case 'oct':
            dtMonth = '10';
            break;
        case 'nov':
            dtMonth = '11';
            break;
        case 'dec':
            dtMonth = '12';
            break;
    }

    // convert date to number
    dtMonth = parseInt(dtMonth);

    if (isNaN(dtMonth)) return false;
    else if (dtMonth < 1 || dtMonth > 12) return false;
    else if (dtDay < 1 || dtDay > 31) return false;
    else if ((dtMonth == 4 || dtMonth == 6 || dtMonth == 9 || dtMonth == 11) && dtDay == 31) return false;
    else if (dtMonth == 2) {
        var isleap = (dtYear % 4 == 0 && (dtYear % 100 != 0 || dtYear % 400 == 0));
        if (dtDay > 29 || (dtDay == 29 && !isleap)) return false;
    }

    return true;
}

jsFiddle

js小提琴

Alternate Solution

替代解决方案

You might not like a really complicated regex, but you can really reduce your code by handling the switching in the regex itself. The following gets the matched month by looping through the matched group into an undefined one is not encountered and then offsetting the value.

您可能不喜欢非常复杂的正则表达式,但您可以通过处理正则表达式本身的切换来真正减少代码。下面通过将匹配的组循环到一个未定义的未遇到的组然后偏移值来获取匹配的月份。

function isDate(currVal) {

    if (currVal == '') return false;

    //Declare Regex  
    var rxDatePattern = /^(\d{1,2})(\/|-)(?:(\d{1,2})|(jan)|(feb)|(mar)|(apr)|(may)|(jun)|(jul)|(aug)|(sep)|(oct)|(nov)|(dec))(\/|-)(\d{4})$/i;

    var dtArray = currVal.match(rxDatePattern);

    if (dtArray == null) return false;

    var dtDay = parseInt(dtArray[1]);
    var dtMonth = parseInt(dtArray[3]);
    var dtYear = parseInt(dtArray[17]);

    if (isNaN(dtMonth)) {
        for (var i = 4; i <= 15; i++) {
            if ((dtArray[i])) {
                dtMonth = i - 3;
                break;
            }
        }
    }

    if (dtMonth < 1 || dtMonth > 12) return false;
    else if (dtDay < 1 || dtDay > 31) return false;
    else if ((dtMonth == 4 || dtMonth == 6 || dtMonth == 9 || dtMonth == 11) && dtDay == 31) return false;
    else if (dtMonth == 2) {
        var isleap = (dtYear % 4 == 0 && (dtYear % 100 != 0 || dtYear % 400 == 0));
        if (dtDay > 29 || (dtDay == 29 && !isleap)) return false;
    }

    return true;
}

jsFiddle

js小提琴

回答by collapsar

your regex is ok, you haven't enclosed the month subpattern with parentheses so you haven't defined a capture group. consequently, your switch statement fails:

你的正则表达式没问题,你没有用括号括起月份子模式,所以你没有定义捕获组。因此,您的 switch 语句失败:

try

尝试

var rxDatePattern = /^(\d{1,2})(\/|-)([a-zA-Z]{3})(\/|-)(\d{4})$/;

and

var dtYear = dtArray[5];  // now 5 instead of 4

回答by jozxyqk

It looks like there's just brackets missing around the month section to make it a separate group.

看起来月份部分周围缺少括号以使其成为一个单独的组。

        /^(\d{1,2})(\/|-)([a-zA-Z]{3})(\/|-)(\d{4})$/

        var dtDay = dtArray[1];
        var dtMonth = dtArray[3];
        var dtYear = dtArray[5];

回答by James Montagne

You need parentheses around the month to capture it:

您需要在月份周围使用括号来捕获它:

/^(\d{1,2})(\/|-)([a-zA-Z]{3})(\/|-)(\d{4})$/

Which will mean you then need to adjust the index of your year:

这意味着您需要调整您的年份指数:

var dtYear = dtArray[5];  // now 5 instead of 4

回答by Logan Murphy

Here is the code, no regexp required and use of javascript build in date parsing.

这是代码,不需要正则表达式,并且在日期解析中使用 javascript 构建。

var isDate = (function() {
    var MONTHS = [
        "Jan", 
        "Feb", 
        "Mar", 
        "Apr", 
        "May", 
        "Jun", 
        "Jul",
        "Aug",
        "Sep",
        "Oct",
        "Nov",
        "Dec"
    ];

    return function (date) {
        var v = new Date(date);
        var day = v.getDate();
        if(day < 10) {
            day = "0" + day;
        }
        var month = MONTHS[v.getMonth()];
        var year = v.getFullYear();
        var total = day + "-" + month + "-" + year;
        return date.toUpperCase() == total.toUpperCase();
    }
}());

THE FIDDLE

小提琴