正则表达式日期模式格式验证未按预期工作



我正在尝试验证日期格式输入。输入不是实际日期,而是DMY输入。而且我不想验证实际日期!只是格式。

我想评估使用双D、双M、双Y-_除法器完成的任何输入。

我当前的正则表达式如下所示:^(?=.*[mM]{2})(?=.*[dD]{2})(?=.*[yY]{2,4})(?=.*[-_]{0,2}).*$

但是,即使找到的字符超过预期字符,这也为真。限制器似乎{2}没有效果。

例如:即使有多个mmmddyyyymmmmmm也会评估 true。 我不明白。

预期结果是,只有以下组合才能测试 true:

dd-mm-yy
MM-DD_YYYY
yyyy_dd-MM
mmddyy
YYYYddMM

而不是像这样的东西:

ddyyyyymmmmmmmmm
mmddyymm

请帮助我更正我的正则表达式。

通常,匹配一个只能匹配包含允许块的字符串的字符串,然后使用一些编程方法来完成其余的"计数"工作是有意义的(你只需检查有多少mmdd,或yyyy/yy(。

如果必须使用正则表达式,有两种方法。

解决方案#1:枚举所有备选方案

这是最不舒服,不是动态/不可扩展的解决方案,您只需在单个组中收集所有可能的模式:

^(?:
[dD]{2}[_-]?[mM]{2}[_-]?[yY]{2}(?:[yY]{2})? |
[mM]{2}[_-]?[dD]{2}[_-]?[yY]{2}(?:[yY]{2})? |
[mM]{2}[_-]?[yY]{2}(?:[yY]{2})?[_-]?[dD]{2} |
[dD]{2}[_-]?[yY]{2}(?:[yY]{2})?[_-]?[mM]{2} |
[yY]{2}(?:[yY]{2})?[_-]?[dD]{2}[_-]?[mM]{2} |
[yY]{2}(?:[yY]{2})?[_-]?[mM]{2}[_-]?[dD]{2}
)$

请参阅正则表达式演示。^断言字符串开头的位置,(?:...|...)具有替代项的非捕获组,$断言字符串的结尾。

解决方案#2:动态方法

这种方法意味着匹配一个只包含三个DMY块的字符串,并用积极的前瞻来限制模式,这将要求字符串只包含每个块的一次出现。瓶颈和问题是块是多字符字符串,因此您需要使用缓和的贪婪令牌(或解开它,使正则表达式更加可怕(:

^
(?=(?:(?![mM]{2}).)*[mM]{2}(?:(?![mM]{2}).)*$)
(?=(?:(?![dD]{2}).)*[dD]{2}(?:(?![dD]{2}).)*$)
(?=(?:(?![yY]{2}(?:[yY]{2})?).)*[yY]{2}(?:[yY]{2})?(?:(?![yY]{2}(?:[yY]{2})?).)*$)
(?:
(?:[mM]{2}|[dD]{2}|[yY]{2}(?:[yY]{2})?)
(?:[_-](?!$))?
){3}
$

查看正则表达式演示

所以,在这里,(?:[mM]{2}|[dD]{2}|[yY]{2}(?:[yY]{2})?)(?:[_-](?!$))?部分从头到尾重复 3 次,所以,字符串可以包含三次出现的dym,即使它们是相同的(mmmmmm也会匹配(。前瞻都是(?=(?:(?!BLOCK).)*BLOCK(?:(?!BLOCK).)*$)的形式 - 仅当有任何文本但 BLOCK 时匹配,然后是 BLOCK,然后是除 BLOCK 之外的任何文本,直到字符串的末尾。

最新更新