我希望能够匹配格式为mm/dd/yy或mm/dd/yyyy的日期,但不应该选择月份无效的23/09/2010,也不应该选择一些无效的日期,如00/12/2020或12/00/2011。
相较于一个非常庞大的正则表达式(假设这是用于验证而不是扫描),以下方法更好:
require 'date'
def valid_date?( str, format="%m/%d/%Y" )
Date.strptime(str,format) rescue false
end
补充一句:呃!为什么要使用如此糟糕的日期格式?选择国际标准的ISO8601,即YYYY-MM-DD
,它有一个一致的部分排序和字典序排序。
'2014-01-01 > '2013-12-12' = true
。如果使用 mm/dd/yy
或类似的格式,这种方法将失败。 - Subtletree最好对斜杠 / 进行拆分,并测试每个单独的部分。但如果你真的想要使用正则表达式,你可以尝试这个:
#\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
我已经解释了第一个部分,把剩下的部分作为练习留给你。
这个匹配项是针对除了 1900 年 02 月 29 日之外的任何日期,而该日期是无效的。
\A
和\z
而不是^
和$
。 - PhrogzDate.parse "some random date"
。如果解析失败(即日期无效),则会收到 ArgumentException 错误提示。DateTime.parse('60201-4286').to_s
返回"2060-07-19T00:00:00+00:00"
而且不会失败。 - dev_rowDateTime.parse('monoxide')
=> #<DateTime: 2019-11-25T00:00:00+00:00 ((2458813j,0s,0n),+0s,2299161j)>
- Jan Krupa使用正则表达式最好的方法是验证格式,例如:
[0-1][0-9]/[0-3][0-9]/[0-9]{2}(?:[0-9]{2})?
除此之外,如果没有某种日期字典,就无法可靠地完成更多操作。例如,一个日期的有效性取决于它是否是闰年。
对于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/中的匹配项
这是你可以使用的代码 :), 试一下并告诉我:
^([0-2][0-9]|(3)[0-1])(\/)(((0)[0-9])|((1)[0-2]))(\/)\d{4}$
00/00/0000
,不确定它是否是一个有效的日期!它也匹配了 31/02/2000
或 31/06/2018
但不匹配 06/06/18
。此外,OP想要的日期格式是 mm/dd/yy
或 mm/dd/yyyy
。 - Toto所以你想要一个能匹配 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 的内容,以及其他符合该格式的日期。我认为这也是您可以找到的最短的针对该格式的正则表达式。