正则表达式匹配日期中的有效日期

Zer*_*obu 10 regex validation perl date

我需要帮助提出正则表达式以确保用户输入有效日期字符串将采用格式 mm/dd/yyyy

这是我到目前为止所提出的.

/\[1-9]|0[1-9]|1[0-2]\/\d{1,2}\/19|20\d\d/
Run Code Online (Sandbox Code Playgroud)

我已经验证了正则表达式,用户无法输入高于12的日期,并且年份必须以"19"或"20"开头.我遇到麻烦的是找出验证当天的一些逻辑.这一天不应该超过31.

blu*_*ume 36

正则表达式为0-31:

(0[1-9]|[12]\d|3[01])
Run Code Online (Sandbox Code Playgroud)

或者如果你不想要前一个零的日子(例如05):

([1-9]|[12]\d|3[01])
Run Code Online (Sandbox Code Playgroud)

  • 那是因为日期不一定有效.例如,它不会拒绝2011年2月31日.正则表达式它是错误的工具. (3认同)
  • 这不允许以零结尾的天数-“ 10”或“ 20”。 (3认同)

Ryl*_*ley 13

use DateTime;
Run Code Online (Sandbox Code Playgroud)

其他的解决方案很好,可能是有效的,等等.通常,你最终想要做更多,然后再多一点,最后你有一些疯狂的代码,闰年,为什么你自己再做一次呢?

DateTime及其格式化程序是您的解决方案.使用它们!有时他们有点矫枉过正,但往往会让你在路上行动起来.

my $dayFormat = new DateTime::Format::Strptime(pattern => '%d/%m/%Y');
my $foo = $dayFormat->parse_datetime($myDateString);
Run Code Online (Sandbox Code Playgroud)

$foo现在是一个DateTime对象.请享用.

如果您的日期字符串格式不正确,$foo将会"undef"并且$dayFormat->errstr会告诉您原因.


Ken*_*war 8

  • 正如上面提到的那样,如果我们想要整体验证日期,那么RegEx是一个非常糟糕的选择.
  • 但是如果我们想匹配一个数字模式,在这种情况下01-31从那时起RegEx就可以了,只要有一些后端逻辑可以验证整个日期,如果需要的话.
  • 我看到目前的预期答案是10,20.

    • 测试: gawk 'BEGIN{ for(i=0;i<=32;i++){ if (i ~ /^([0-2]?[1-9]|3[01])$/){print i " yes"}else {print i " no"} } }
    • 这可以更正如下: ^([0-2]?[1-9]|3[01]|10|20)$

请仔细考虑以下解决方案......

1.确定需要匹配的集合:

  • 前缀为"0"的天数: {01,...,09},{10,...,31}
    • 子集{10,...,31}可以拆分成=> {10,...,29},{30,31}
  • 没有任何前缀: {1,...,31} => {1,...,9},{10,...,31}

2.每个子集的相应正则表达式:

---------------------------------
Sub-Set     |  Regular-Expression
---------------------------------
{01,...,09} | [0][1-9]
{10,...,29} | [1-2][0-9]
{30,31}     | 3[01]
{1,...,9}   | [1-9]
---------------------------------
Run Code Online (Sandbox Code Playgroud)

现在我们可以分组([0][1-9])([1-9])一起作为([0]?[1-9]).其中?表示模式/符号出现0或1次.[更新] - 谢谢@MattFrear指出它.

因此产生的RegEx是: ^(([0]?[1-9])|([1-2][0-9])|(3[01]))$

在此测试:http ://regexr.com/?383k1 [更新]

  • 对已接受答案的改进.但是,这会接受001,00000001等我建议^(([0]?[1-9])|([1-2] [0-9])|(3 [01]))$ http: //regexr.com?383k1 (2认同)

Set*_*son 5

^(((((((0?[13578])|(1[02]))[\.\-/]?((0?[1-9])|([12]\d)|(3[01])))|(((0?[469])|(11))[\.\-/]?((0?[1-9])|([12]\d)|(30)))|((0?2)[\.\-/]?((0?[1-9])|(1\d)|(2[0-8]))))[\.\-/]?(((19)|(20))?([\d][\d]))))|((0?2)[\.\-/]?(29)[\.\-/]?(((19)|(20))?(([02468][048])|([13579][26])))))$
Run Code Online (Sandbox Code Playgroud)

类别中的表达式:日期和时间

验证一个月内的正确天数,看起来甚至可以处理闰年.

当然,你可以改变[\.\-/]/只允许斜杠.

  • +为一个滑稽的复杂性.@Zerobu,希望这能告诉你为什么正则表达式对这个问题是一个坏主意!即便是这个野兽也不完全正确:正如原作者所说,它与02/29/1900不匹配. (12认同)