正则表达式匹配日期

时间:2011-05-12 13:13:37

标签: ruby regex

我希望将日期与格式mm / dd / yy或mm / dd / yyyy匹配,但不应该选择23/09/2010,其中月份为23,无效或者无效日期为00/12/2020或12 / 00/2011。

7 个答案:

答案 0 :(得分:37)

比疯狂的巨大正则表达式更好(假设这是用于验证而不是扫描):

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

作为一篇社论:Eww!你为什么要使用如此可怕的日期格式呢?转到ISO8601,YYYY-MM-DD,这是一个有效的国际标准,具有一致的零件排序,并按字典顺序排序。

答案 1 :(得分:25)

你最好分开/测试所有单独的部分。但是如果你真的想使用正则表达式,你可以尝试这个:

#\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#

说明:

\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

我已经解释了第一部分,剩下的就是练习。

这个匹配一个无效的日期:02/29/1900但是对于01/01/1900和12/31/2099之间的任何其他日期是正确的

答案 2 :(得分:8)

或者您只是使用Date.parse "some random date" 如果解析失败,你将得到一个ArgumentException(=>日期无效)。

参见例如http://santoro.tk/mirror/ruby-core/classes/Date.html#M000644

答案 3 :(得分:2)

使用regexp可以做的最好的事情是验证格式,例如类似的东西:

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

如果没有某种日期字典,除此之外的任何事情都无法可靠地完成。例如,日期的有效性取决于它是否是闰年。

答案 4 :(得分:1)

对于MM-DD-YYYY,您可以使用以下正则表达式。它将在闰年工作,并且只会匹配正确的日期,除非年份不超过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))))

http://regexr.com/

中的结帐匹配

答案 5 :(得分:0)

所以你想要一个匹配为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}$

这个正则表达式将完全匹配您想要的格式mm / dd / yy并不会验证任何假日期,您可以在regex101上测试正则表达式 您可以测试12/30/2040和09/09/2020的日期以及您想要的格式,我认为这也是您可以找到的最短格式

答案 6 :(得分:0)

这是代码而不是你可以使用:),试试看并告诉我:

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