简体   繁体   中英

Regex to match Date

我想匹配格式为 mm/dd/yy 或 mm/dd/yyyy 的日期,但它不应该选择 23/09/2010,其中月份是 23,这是无效的,也不是一些无效的日期,如 00/12/2020 或 12/00/ 2011 年。

Better than a crazy huge Regex (assuming this is for validation and not scanning):

require 'date'
def valid_date?( str, format="%m/%d/%Y" )
  Date.strptime(str,format) rescue false
end

And as an editorial aside: Eww! Why would you use such a horribly broken date format? Go for ISO8601, YYYY-MM-DD , which is a valid international standard, has a consistent ordering of parts, and sorts lexicographically as well.

You'd better do a split on / and test all individual parts. But if you really want to use a regex you can try this one :

#\A(?:(?:(?:(?:0?[13578])|(1[02]))/31/(19|20)?\d\d)|(?:(?:(?:0?[13-9])|(?:1[0-2]))/(?:29|30)/(?:19|20)?\d\d)|(?:0?2/29/(?:19|20)(?:(?:[02468][048])|(?:[13579][26])))|(?:(?:(?:0?[1-9])|(?:1[0-2]))/(?:(?:0?[1-9])|(?:1\d)|(?:2[0-8]))/(?:19|20)?\d\d))\Z#

Explanation:

\A           # start of string
 (?:         # group without capture
             # that match 31st of month 1,3,5,7,8,10,12
   (?:       # group without capture
     (?:     # group without capture
       (?:   # group without capture
         0?  # number 0 optionnal
         [13578] # one digit either 1,3,5,7 or 8
       )     # end group
       |     # alternative
       (1[02]) # 1 followed by 0 or 2
     )       # end group
     /       # slash
     31      # number 31
     /       # slash
     (19|20)? #numbers 19 or 20 optionnal
     \d\d    # 2 digits from 00 to 99 
   )         # end group
|
   (?:(?:(?:0?[13-9])|(?:1[0-2]))/(?:29|30)/(?:19|20)?\d\d)
|
   (?:0?2/29/(?:19|20)(?:(?:[02468][048])|(?:[13579][26])))
|
   (?:(?:(?:0?[1-9])|(?:1[0-2]))/(?:(?:0?[1-9])|(?:1\d)|(?:2[0-8]))/(?:19|20)?\d\d)
 )
\Z

I've explained the first part, leaving the rest as an exercise.

This match one invalid date : 02/29/1900 but is correct for any other dates between 01/01/1900 and 12/31/2099

Or you simply use Date.parse "some random date" .
You'll get an ArgumentException if it fails parsing (=> Date is invalid).

See eg http://santoro.tk/mirror/ruby-core/classes/Date.html#M000644

The best you can do with a regexp is to validate the format, eg something like:

[0-1][0-9]/[0-3][0-9]/[0-9]{2}(?:[0-9]{2})?

Anything beyond that cannot be reliably done without some kind of date dictionary. A date's validity depends on whether it's a leap year or not, for instance.

For MM-DD-YYYY you could use the below regex. It'll work for leap years, and will match correct dates only unless the year doesn't exceed 2099.

(?:(09|04|06|11)(\/|-|\.)(0[1-9]|[12]\d|30)(\/|-|\.)((?:19|20)\d\d))|(?:(01|03|05|07|08|10|12)(\/|-|\.)(0[1-9]|[12]\d|3[01])(\/|-|\.)((?:19|20)\d\d))|(?:02(\/|-|\.)(?:(?:(0[1-9]|1\d|2[0-8])(\/|-|\.)((?:19|20)\d\d))|(?:(29)(\/|-|\.)((?:(?:19|20)(?:04|08|12|16|20|24|28|32|36|40|44|48|52|56|60|64|68|72|76|80|84|88|92|96))|2000))))

Checkout matches in http://regexr.com/

so you want a regex that will match as mm/dd/yy

^((0?1?1){1}|(0?1?2){1}|([0]?3|4|5|6|7|8|9))\/((0?1?2?3?1){1}|(0?1?2?(2|3|4|5|6|7|8|9|0))|(30))\/[1-90]{4}$

this regex will match exactly what you want in that format mm/dd/yy an will not validate any fake date you can test the regex on regex101 you can test for the dates 12/30/2040 and 09/09/2020 and what ever you want for that format i think this is also the shortest regex you can find for that format

这是您可以使用的代码:),尝试一下并告诉我:

 ^([0-2][0-9]|(3)[0-1])(\\/)(((0)[0-9])|((1)[0-2]))(\\/)\\d{4}$

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM