使用Regex检查有效日期组合?

时间:2014-01-06 08:08:49

标签: javascript regex

用户可以在输入中输入一些有效的日期组合:

示例:(允许所有组合3!= 6)

feb 7 2012
feb 07 2012
7 feb 2012
2012 7 feb
...

所有都是有效日期。

我还设法创建了一个检查它的正则表达式:

/^(?=.*\b(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)\b)(?=.*(\b[1‌2]\d{3}\b))(?=.*\b(0[1-9]|[12]\d|3[01])\b).*$/i

这意味着:

  • (?=.*\b(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)\b):我预计将来会有其中一个值。
  • (?=.*(\b[1‌2]\d{3}\b)):我期待一年:1xxx或2xxx
  • (?=.*\b(0[1-9]|[12]\d|3[01])\b)我期待的一天:0x或1x或2x或3x

一切都好。

问题出在哪里?

我的正则表达式还匹配无效的解决方案包含有效的解决方案:

IE:feb 13 2012 4也将通过。

Console : 

/^(?=.*\b(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)\b)(?=.*(\b[1‌2]\d{3}\b))(?=.*\b(0[1-9]|[12]\d|3[01])\b).*$/i.test('feb 13 2012 4') //true

问题:

如何增强我的正则表达式才能找到严格匹配?

P.S。 检查new Date(xxx)也是一种解决方案,但我正在寻找正则表达式解决方案。(以提高我的正则表达式技能)。

2 个答案:

答案 0 :(得分:4)

为每种格式写一个正则表达式:

  • RE1 - 识别MON DD YYYY = (?:JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)\s+(?:0?[1-9]|[12]\d|3[01])\s+[12]\d{3}
  • RE2 - 识别DD MON YYYY = (?:0?[1-9]|[12]\d|3[01])\s+(?:JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)\s+[12]\d{3}
  • RE3 - 识别YYYY DD MON = [12]\d{3}\s+(?:0?[1-9]|[12]\d|3[01])\s+(?:JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)

然后结合它们:

/^(?:RE1|RE2|RE3)$/i

答案 1 :(得分:2)

在开头创建一个前瞻(?=...)组,然后在月份块之前或之后创建数字的可选组。下面的正则表达式适用于所有示例(请参阅链接页面上的单元测试)。 修改:它现在匹配所有3!= 6个允许的组合,但不包含2 feb 1978 4等不允许的组合。

/^(?=[a-z]{3}\s(\d{1,2}\s\d{4}|\d{4}\s\d{1,2})$|\d{1,2}\s[a-z]{3}\s\d{4}$|\d{4}\s[a-z]{3}\s\d{1,2}$|(\d{1,2}\s\d{4}|\d{4}\s\d{1,2})\s[a-z]{3}$)([12]\d{3}\s|\d{1,2}\s){0,2}(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)(\s\d{1,2}|\s[12]\d{3}){0,2}$/i

Regular expression visualization

Debuggex Demo

说明:

  • 整个表达式必须如下所示:
    • [a-z]中的三个,然后是一天,然后是一年
    • [a-z]中的三个,然后是一年,然后是一天
    • 一天,三天[a-z]和一年
    • 一年,三个[a-z]和一天
    • [a-z]
    • 中的一天,一年,三天
    • 一年,一天,然后三[a-z]
  • 可选择匹配一个或两个数字组
  • 匹配三个字母的月份代码
  • 可选择匹配一个或两个数字组