为什么我的日期验证正则表达式不能识别二月(和其他人)?

时间:2011-07-13 16:00:01

标签: javascript regex date

我正在制作一个应该与月日格雷戈日期(javascript)相匹配的正则表达式,它适用于1月,3月,5月,7月,8月,10月和12月(31天的月份) )约会,但由于某些我无法弄清楚的原因,它不会与任何其他月份的任何日期相匹配。

对以下代码的一点解释:我将其设置为首次匹配日期的月 - 日部分,因此例如在2月31日它不匹配。所以,我目前已经匹配(((一个31天的月份)THEN(一个非字母数字字符,已捕获)然后(从1到31的一天))或((28天一个月)然后(非字母数字字符,捕获)然后(从1到29的一天))或((30天一个月)那么(一个非字母数字字符,捕获)然后(从1到30的一天)))然后(之前捕获)那个(AD过去或当年)。

我确信这个问题很简单,但我只是没有看到它。

^
(?:
  (?:
    (?:0?[13578]|1[02])
    ([^\dA-Za-z])
    (?:0?[1-9]|1[0-9]|2[0-9]|3[01])
  )
  |
  (?:
    (?:0?2)
    ([^\dA-Za-z])
    (?:0?[1-9]|1[0-9]|2[0-9])
  )
  |
  (?:
    (?:0?[469]|11)
    ([^\dA-Za-z])
    (?:0?[1-9]|1[0-9]|2[0-9]|30)
  )
)
\1
(?:0{0,3}[1-9]|0{0,2}[1-9][0-9]|0?[1-9][0-9]{2}|1[0-9]{3}|200[0-9]|201[01])
$

2 个答案:

答案 0 :(得分:2)

您收到此错误是因为您使用的\1与最后2次更改不匹配。 \1指的是第一个 ([^\dA-Za-z]) - 如果它不匹配,则无法进入年份。

一个简单的替代方案是(?:\1|\2|\3)

另一种选择是在模式(?=\d+([^\dA-Za-z]))的开头添加,并在所有地方使用\1。例如:

^
(?=\d+([^\dA-Za-z]))   # capture the separator as \1
(?:
  (?:
    (?:0?[13578]|1[02])
    \1
    (?:0?[1-9]|1[0-9]|2[0-9]|3[01])
  )
  |
  (?:
    (?:0?2)
    \1
    (?:0?[1-9]|1[0-9]|2[0-9])
  )
  |
  (?:
    (?:0?[469]|11)
    \1
    (?:0?[1-9]|1[0-9]|2[0-9]|30)
  )
)
\1
(?:0{0,3}[1-9]|0{0,2}[1-9][0-9]|0?[1-9][0-9]{2}|1[0-9]{3}|200[0-9]|201[01])
$

旁注: yikes!试试Datejs - 一个令人印象深刻的开源JavaScript日期库。

答案 1 :(得分:1)

您的问题是\1反向引用。它指的是您第一次轮换中的([^\dA-Za-z])组匹配(31天 - 月)。要匹配第二个轮换的分隔符,您需要\2等。

因此,您可能希望使用(?:\1|\2|\3)而不是\1,除非在JavaScript中也出现错误。

最后,你知道这还没有正确验证日期吗?想想闰年......