如何将此正则表达式转换为接受格式mm-dd-yyyy?

时间:2013-03-31 21:08:46

标签: regex

到目前为止,这是我的正则表达式

/^((((0?[1-9]|[12]\d|3[01])[\-\/](0?[13578]|1[02])[\-\/]((1[6-9]|[2-9]\d)?\d{2}))|((0?[1-9]|[12]\d|30)[\-\/](0?[13456789]|1[012])[\-\/]((1[6-9]|[2-9]\d)?\d{2}))|((0?[1-9]|1\d|2[0-8])[\-\/]0?2[\-\/]((1[6-9]|[2-9]\d)?\d{2}))|(29[\-\/]0?2[\-\/]((1[6-9]|[2-9]\d)?(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00)|00)))|(((0[1-9]|[12]\d|3[01])(0[13578]|1[02])((1[6-9]|[2-9]\d)?\d{2}))|((0[1-9]|[12]\d|30)(0[13456789]|1[012])((1[6-9]|[2-9]\d)?\d{2}))|((0[1-9]|1\d|2[0-8])02((1[6-9]|[2-9]\d)?\d{2}))|(2902((1[6-9]|[2-9]\d)?(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00)|00))))$/i

它确实完成了日期验证,包括闰年,但它接受的格式是dd-mm-yyyy,我想要mm-dd-yyyy。它也接受我不想要的年份的两位数。

3 个答案:

答案 0 :(得分:3)

从示例开发复杂正则表达式的最简单方法是使用http://txt2re.com处的正则表达式生成器

答案 1 :(得分:2)

//你可以投票或将其标记为“不是答案”,但我无法拒绝发布此内容......

哦,你为什么这么恨自己?

正则表达式是一个强大而有用的工具,但它无法解决这个世界上的每一个问题。 一遍又一遍,我看到尝试解析这样的日期 - 尊重闰年,或用正则表达式解析XML / HTML。

这是错误的

你的正则表达式是不可读的,并且不可维护(你已经通过这个问题证明了这一点)。构建这样的 monster-regexps 作为练习可能会很好,但你甚至不应该考虑在生产环境中使用它。

原因是(仅举几例!):

  • 正确性:你不确定这是否有效。您将花费数小时来分析和测试它。

  • 性能:此类大小的正则表达式可能需要很长时间才能执行。

  • 错误输出:正则表达式只为您提供“匹配/不匹配”结果。您没有机会告诉用户他输入的日期是语法无效还是 2月29日今年不存在

了解如何为特定目的选择合适的工具。一个普遍的“我可以做的一切都好”的工具不存在。

答案 2 :(得分:1)

哇。我真的怀疑正则表达式是走到这里的方式......但是,好吧,让我们试一试。

首先重新格式化正则表达式以使其更具可读性。如您所见,它包含许多替代方案。添加评论:

/^
 (
  (
   ((0?[1-9]|[12]\d|3[01])-/-/)    # dd-/-/
   |
   ((0?[1-9]|[12]\d|30)-/-/)       # dd-/-/ (uh, this seems redundant?)
   |
   ((0?[1-9]|1\d|2[0-8])[-/]0?2-/) # dd-/-/ (february)
   |
   (29[-/]0?2-/)
  )
  |
  (
   (
    (0[1-9]|[12]\d|3[01])     # day
    (0[13578]|1[02])          # month
    ((1[6-9]|[2-9]\d)?\d{2})  # year
   )
   |
   (
    (0[1-9]|[12]\d|30)        # day
    (0[13456789]|1[012])      # month
    ((1[6-9]|[2-9]\d)?\d{2})  # year
   )
   |
   (
    (0[1-9]|1\d|2[0-8])       # day
    02                        # month
    ((1[6-9]|[2-9]\d)?\d{2})  # year
   )
   |
   (
    2902                      # day and month
    (                         # year in which there's a 29-02-xxxx
     (1[6-9]|[2-9]\d)?
     (0[48]|[2468][048]|[13579][26])
     |
     ((16|[2468][048]|[3579][26])00)
     |
     00
    )
   )
  )
 )
$/i

接下来,重新排序正则表达式,将其从ddmmyyyy更改为mmddyyyy:

/^
 (
  (
   (-/(0?[1-9]|[12]\d|3[01])-/)    # -/dd-/
   |
   (-/(0?[1-9]|[12]\d|30)-/)       # -/dd-/ (uh, this seems redundant?)
   |
   ([-/]0?2(0?[1-9]|1\d|2[0-8])-/) # -/dd-/ (february) (I don't really get this one...)
   |
   ([-/]0?229-/) # really confused... what kind of date format is this?
  )
  |
  (
   (
    (0[13578]|1[02])          # month
    (0[1-9]|[12]\d|3[01])     # day
    ((1[6-9]|[2-9]\d)?\d{2})  # year
   )
   |
   (
    (0[13456789]|1[012])      # month
    (0[1-9]|[12]\d|30)        # day
    ((1[6-9]|[2-9]\d)?\d{2})  # year
   )
   |
   (
    02                        # month
    (0[1-9]|1\d|2[0-8])       # day
    ((1[6-9]|[2-9]\d)?\d{2})  # year
   )
   |
   (
    0229                      # day and month
    (                         # year in which there's a 29-02-xxxx
     (1[6-9]|[2-9]\d)?
     (0[48]|[2468][048]|[13579][26])
     |
     ((16|[2468][048]|[3579][26])00)
     |
     00
    )
   )
  )
 )
$/i

请注意,我对包含-/的日期格式感到困惑,因此可能无法正确重写它们。

然后将其放入您的代码中。如果你不想让某人死于致命剂量的难以理解的正则表达式,请保留评论(如果你的编程语言允许的话)。