【问题标题】:regex to validate date in DD.MM format正则表达式以 DD.MM 格式验证日期
【发布时间】:2016-09-28 19:15:56
【问题描述】:

我搜索了很多正则表达式来验证 DD.MM.YYYY 格式的日期。喜欢这个:

(0[1-9]|1[0-9]|2[0-8]|(?:29|30)(?!.02)|29(?=.02.\d\d(?:[02468][048]|[13579][26]))|31(?=.0[13578]|.1[02]))(?:\.(?=\d\d\.)|-(?=\d\d-)|\/(?=\d\d\/))(0[1-9]|1[0-2])[.\/\-]([1-9][0-9]{3})

而且效果很好。

据我了解,([1-9][0-9]{3}) 部分指的是年份。我尝试删除它,它开始验证以点结尾的日期,例如01.05.10.07. 等。

>>> regex = '^(0[1-9]|1[0-9]|2[0-8]|(?:29|30)(?!.02)|29(?=.02.\d\d(?:[02468][048]|[13579][26]))|31(?=.0[13578]|.1[02]))(?:\.(?=\d\d\.)|-(?=\d\d-)|\/(?=\d\d\/))(0[1-9]|1[0-2])[.\/\-]$'
>>> aaa = '12.02.'
>>> bbb = '32.02.'
>>> print(re.match(regex, aaa))
<_sre.SRE_Match object; span=(0, 6), match='12.02.'>
>>> print(re.match(regex, bbb))
None

但是当我删除处理点/破折号分隔符的部分时

[.\/\-]

它不会验证没有尾随点的日期:

>>> regex = '^(0[1-9]|1[0-9]|2[0-8]|(?:29|30)(?!.02)|29(?=.02.\d\d(?:[02468][048]|[13579][26]))|31(?=.0[13578]|.1[02]))(?:\.(?=\d\d\.)|-(?=\d\d-)|\/(?=\d\d\/))(0[1-9]|1[0-2])$'
>>> aaa = '12.02'
>>> bbb = '32.02'
>>> print(re.match(regex, aaa))
None
>>> print(re.match(regex, bbb))
None

我该如何进行这项工作?

关于 2 月 28 日/2 月 29 日的更新:

如果 2 月 28 日/29 日无法验证也没关系,在我的情况下这是可以接受的。

关于 Python 的更新:

我不能为此使用 python 验证,遗憾的是它只是我可以使用的网络表单中的一个正则表达式字段。

【问题讨论】:

  • 恕我直言,使用这样的正则表达式来验证日期是错误的。最好用句点分隔符分割输入字符串,然后检查年/月/日是否有效。也许它的代码行数更多,但它肯定会更具可读性。
  • How to validate a date?的可能重复
  • 我认为你做不到:乍一看,这个复杂的正则表达式需要年份来验证日期(否则它怎么知道 2 月是 28 天还是 29 天?)
  • @AndrewMorton:当 OP 使用 Python 时,此链接到 JS 问题。
  • @Jan 谢谢!没有人告诉我这是 Python。现在我不能用In python, how to check if a date is valid?进行VTC

标签: python regex


【解决方案1】:

解决方案

 ^(0[1-9]|[12][0-9]|30(?!\.02)|31(?!\.(0[2469]|11)))\.(0[1-9]|1[0-2])$

python 中的示例

>>> daymonth_match = r"^(0[1-9]|[12][0-9]|30(?!\.02)|31(?!\.(0[2469]|11)))\.(0[1-9]|1[0-2])$"
>>> print re.match(daymonth_match, "12.04")
<_sre.SRE_Match object at 0x7f3728125880>
>>> print re.match(daymonth_match, "29.02")
<_sre.SRE_Match object at 0x7f3728125880>
>>> print re.match(daymonth_match, "30.02")
None
>>> print re.match(daymonth_match, "30.04")
<_sre.SRE_Match object at 0x7f3728125880>
>>> print re.match(daymonth_match, "31.04")
None
>>> print re.match(daymonth_match, "31.05")
<_sre.SRE_Match object at 0x7f3728125880>

它假定29.02 始终有效。

关于它如何工作的一些细节

这个正则表达式依赖于否定的前瞻断言(?!...)。 例如,表达式30(?!\.02) 意味着30 仅当它后面没有\.02 AND 时才匹配,因为它是“前瞻”,\.02 不被视为表达式本身的匹配(详情见python documentation

【讨论】:

    【解决方案2】:

    只需将点和年份设为可选:

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

    【讨论】:

      猜你喜欢
      • 2014-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-23
      相关资源
      最近更新 更多