Regular Expression to match valid dates

2020-01-22 11:55发布

I'm trying to write a regular expression that validates a date. The regex needs to match the following

  • M/D/YYYY
  • MM/DD/YYYY
  • Single digit months can start with a leading zero (eg: 03/12/2008)
  • Single digit days can start with a leading zero (eg: 3/02/2008)
  • CANNOT include February 30 or February 31 (eg: 2/31/2008)

So far I have

^(([1-9]|1[012])[-/.]([1-9]|[12][0-9]|3[01])[-/.](19|20)\d\d)|((1[012]|0[1-9])(3[01]|2\d|1\d|0[1-9])(19|20)\d\d)|((1[012]|0[1-9])[-/.](3[01]|2\d|1\d|0[1-9])[-/.](19|20)\d\d)$

This matches properly EXCEPT it still includes 2/30/2008 & 2/31/2008.

Does anyone have a better suggestion?

Edit: I found the answer on RegExLib

^((((0[13578])|([13578])|(1[02]))[\/](([1-9])|([0-2][0-9])|(3[01])))|(((0[469])|([469])|(11))[\/](([1-9])|([0-2][0-9])|(30)))|((2|02)[\/](([1-9])|([0-2][0-9]))))[\/]\d{4}$|^\d{4}$

It matches all valid months that follow the MM/DD/YYYY format.

Thanks everyone for the help.

标签: regex date
15条回答
一纸荒年 Trace。
2楼-- · 2020-01-22 12:11

Maintainable Perl 5.10 version

/
  (?:
      (?<month> (?&mon_29)) [\/] (?<day>(?&day_29))
    | (?<month> (?&mon_30)) [\/] (?<day>(?&day_30))
    | (?<month> (?&mon_31)) [\/] (?<day>(?&day_31))
  )
  [\/]
  (?<year> [0-9]{4})

  (?(DEFINE)
    (?<mon_29> 0?2 )
    (?<mon_30> 0?[469]   | (11) )
    (?<mon_31> 0?[13578] | 1[02] )

    (?<day_29> 0?[1-9] | [1-2]?[0-9] )
    (?<day_30> 0?[1-9] | [1-2]?[0-9] | 30 )
    (?<day_31> 0?[1-9] | [1-2]?[0-9] | 3[01] )
  )
/x

You can retrieve the elements by name in this version.

say "Month=$+{month} Day=$+{day} Year=$+{year}";

( No attempt has been made to restrict the values for the year. )

查看更多
beautiful°
3楼-- · 2020-01-22 12:13
    var dtRegex = new RegExp(/[1-9\-]{4}[0-9\-]{2}[0-9\-]{2}/);
    if(dtRegex.test(date) == true){
        var evalDate = date.split('-');
        if(evalDate[0] != '0000' && evalDate[1] != '00' && evalDate[2] != '00'){
            return true;
        }
    }
查看更多
聊天终结者
4楼-- · 2020-01-22 12:14

This is not an appropriate use of regular expressions. You'd be better off using

[0-9]{2}/[0-9]{2}/[0-9]{4}

and then checking ranges in a higher-level language.

查看更多
▲ chillily
5楼-- · 2020-01-22 12:14

Sounds like you're overextending regex for this purpose. What I would do is use a regex to match a few date formats and then use a separate function to validate the values of the date fields so extracted.

查看更多
放荡不羁爱自由
6楼-- · 2020-01-22 12:14

if you didn't get those above suggestions working, I use this, as it gets any date I ran this expression through 50 links, and it got all the dates on each page.

^20\d\d-(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)-(0[1-9]|[1-2][0-9]|3[01])$ 
查看更多
何必那么认真
7楼-- · 2020-01-22 12:15

Here is the Reg ex that matches all valid dates including leap years. Formats accepted mm/dd/yyyy or mm-dd-yyyy or mm.dd.yyyy format

^(?:(?:(?:0?[13578]|1[02])(\/|-|\.)31)\1|(?:(?:0?[1,3-9]|1[0-2])(\/|-|\.)(?:29|30)\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:0?2(\/|-|\.)29\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:(?:0?[1-9])|(?:1[0-2]))(\/|-|\.)(?:0?[1-9]|1\d|2[0-8])\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$

courtesy Asiq Ahamed

查看更多
登录 后发表回答