Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/472.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 正在尝试验证YYYY/MM/dd_Javascript_Regex - Fatal编程技术网

Javascript 正在尝试验证YYYY/MM/dd

Javascript 正在尝试验证YYYY/MM/dd,javascript,regex,Javascript,Regex,我知道有很多正则表达式线程在那里,但我找不到任何地方 我有一个正则表达式,可以很好地使用DD/MM/YYYY格式。 这是: ^((0?[13578]|1[02])[\/.]31[\/.][1-9][0-9]{3})|(([01,1]|0[3-9]|1[1-2])[\/.](29|30)[\/.][1-9][0-9]{3})|((0?[1-9]|1[0-2])[\/.](0?[1-9]|1[0-9]|2[0-8])[\/.][1-9][0-9]{3})|([02,2][\/.]29[\/.](([

我知道有很多正则表达式线程在那里,但我找不到任何地方

我有一个正则表达式,可以很好地使用DD/MM/YYYY格式。 这是:

^((0?[13578]|1[02])[\/.]31[\/.][1-9][0-9]{3})|(([01,1]|0[3-9]|1[1-2])[\/.](29|30)[\/.][1-9][0-9]{3})|((0?[1-9]|1[0-2])[\/.](0?[1-9]|1[0-9]|2[0-8])[\/.][1-9][0-9]{3})|([02,2][\/.]29[\/.](([1-9][0-9](04|08|[2468][048]|[13579][26]))|([2468][0]{3})))$
示例:2014年2月29日、2014年4月31日

但当我尝试使用YYYY/MM/DD格式进行验证时,我发现:

^(((19|20)([2468][048]|[13579][26]|0[48])|2000)[\/.]02[\/.]29|((19|20)[0-9]{2}[\/.](0?[469]|11)[\/.](0?[1-9]|[12][0-9]|30)|(19|20)[0-9]{2}[\/.](0?[13578]|1[02])[\/.](0?[1-9]|[12][0-9]|3[01])|(19|20)[0-9]{2}[\/.]02[\/.](0?[1-9]|1[0-9]|2[0-8])))$
此模式仅适用于从19xx->20xxx开始的YYYY

当我更改它时,我希望它可以从1xxx->9xxx与YYYY一起很好地工作。但它做得并不好

我是新来的正则表达式,很难逃避它


非常感谢,很抱歉我的英语不好。

只使用正则表达式验证日期是个坏主意,因为闰年。我将在javascript中使用模式
^\d{4}/\d{1,2}/\d{1,2}$
,并在服务器端执行更完整的验证。这种模式也更容易理解和修改。

TL;Minitech博士和TheQ的评论是正确的——这对于正则表达式来说不是一项伟大的任务。下面给出了一个非正则表达式的解决方案。只是为了好玩,一个怪异的正则表达式也是如此。 编辑:我决定花几分钟的时间在午餐时间清理这个文件,并添加“正确”的方法(没有正则表达式)和JSFIDLE


真正的答案 为了可读性、可维护性和合理性,正确的方法是避免在这里使用正则表达式。编写一个正则表达式来实现这一点是非常困难的,而且结果非常难以阅读

相反,只需将日期解析为其组成部分,然后像这样验证它们:

/**
 * Check whether a given year is a leap year
 * @param integer y The integer
 * @return boolean True for yes, false for no
 */
function isLeapYear(y) {
    return (0 == y % 4 && (0 == y % 400 || 0 != y % 100));
}

/**
 * Validate a date in YYYY/MM/DD format (allows YYYY/M/D and periods instead of slashes) without regex.
 * @param string str The date to test.
 * @return boolean True for valid, false for invalid.
 */
function validateDateWithoutRegex(str) {
    // check the format first
    if(!/^\d{4}[\/.]\d{1,2}[\/.]\d{1,2}$/.test(str)) {
        return false;
    }
    var parts = str.split(/\D/) // split on non-digits
        .map(function(val) { return parseInt(val); }); // convert strings to ints
    if(parts[0] < 1000 || parts[0] > 2999) { // invalid year
        return false;
    }
    if(parts[1] > 12 || parts[1] === 0) { // invalid month
        return false;
    }
    if(parts[2] > 31 || parts[2] === 0) { // invalid day
        return false;
    }
    switch(parts[1]) {
        case 4:
        case 6:
        case 9:
        case 11:
            if(parts[2] > 30) { // invalid day
                return false;
            }
            break;
        case 2: // February...
            return (parts[2] < 29 || parts[2] == 29 && isLeapYear(parts[0]));
            break;
    }
    return true;       
}

// Usage: validateDateWithoutRegex('2014/07/28'); // returns true
这甚至验证了闰年

验证此方法与非正则表达式方法的工作方式相同

可能有帮助的解释,由Debuggex提供:

示例匹配:

  • 2014/12/31
  • 1937/4/17
  • 1066/1/4
  • 1066/2/28
  • 2014/1/1
  • 2012/02/29
  • 2000/02/29(400的倍数是闰年)
  • 1600/02/29(400的倍数是闰年)
  • 2015/01/01
不匹配的示例:

  • 1900/02/29(100的倍数不是400的倍数不是闰年)
  • 2012/02/30
  • 2012/00/01
  • 2012/00/00
  • 2012/04/31
  • 2012/17/01
  • 2012/02/00
  • 1066/1/4444
  • 1066/2/29
  • 1065/2/29
  • 2014/14/1
  • 2014/02/29
时间不早了,希望能给你一些有用的建议

关于两种方法的历史问题的注记 格里高利历与新教改革的历史紧密相连。它在创立时极具争议性,并没有被普遍采用。采用这种方法的地方在不同的时间以不同的方式这样做。结果是:在公历中哪些日期是有效的取决于你在哪里

基本上,公历是1582年产生的。自那时以来,各国对其采用情况各不相同。例如,1582年10月5日至14日的日历基本上已不复存在。许多国家同样跳过了几天来改变旧的(儒略)日历日期以匹配公历,但它们都没有跳过相同的几天(甚至是相同的天数);他们跳过哪几天取决于国家以及何时采用日历


因此,如果您希望能够验证1582年之前的日期(有些地方甚至是1923年),请记住所有这些。玩得开心

你必须使用正则表达式吗?拆分
/
,将每个部分解析为一个整数并进行适当的比较可能会容易得多。+1有助于获得正确的答案。我只是对自己的想法感到可笑。:)谢谢Ed Cottrell和每一个答案,这是一个非常有用的建议。我们如何强制用户总是在月份或日期中输入两个数字?我的意思是我希望我的格式总是YYYY/MM/DD(而不是YYYY/M/D或不是YYYY/M/DD或不是YYYY/MM/D)@user613114这确实是一个新问题,应该作为一个新问题而不是作为评论来问。也就是说,在我的答案中,对格式检查步骤有一个非常简单的调整,可以让你做到这一点。
/^(?=(?!\d+\D0?2\D29)|(?:\d{2}(?:04|08|[13579][26]|[2468][048])|1[26]00|2000)\D0?2\D29$)([12]\d{3})[\/.]((?:0?[13578]|10|12)[\/.](?:0?[1-9]|[12]\d|3[0-1])|(?:0?[469]|11)[\/.](?:0?[1-9]|[12]\d|30)|0?2[\/.](?:0?[1-9]|1\d|2[0-9]))$/