正则表达式匹配日期

Loh*_* MV 16 ruby regex

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

Phr*_*ogz 37

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

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

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

  • 我在较早的时候读过这篇文章,并没有真正理解为什么词典排序是一件好事.它允许您使用字符串比较对日期进行排序或查找最低/最高日期!例如`'2014-01-01>'2013-12-12'= true`.使用`mm/dd/yy`或类似的东西会失败. (2认同)

Tot*_*oto 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#
Run Code Online (Sandbox Code Playgroud)

说明:

\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
Run Code Online (Sandbox Code Playgroud)

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

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


Sim*_*ker 8

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

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

  • 如果您有未经验证的字符串,请小心。例如,使用邮政编码会产生不希望的结果。`DateTime.parse('60201-4286').to_s` 给出了 `"2060-07-19T00:00:00+00:00"` 并且不会失败。 (2认同)