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

时间:2019-09-16 06:08:05

标签: regex

我正在尝试验证日期格式输入。输入的不是实际日期,而是D M Y输入。我不想要验证实际日期!只是格式。

我想评估使用双DM分频器进行双Y,双-,双{或四倍_完成的任何输入。

我当前的RegEx看起来如下: ^(?=.*[mM]{2})(?=.*[dD]{2})(?=.*[yY]{2,4})(?=.*[-_]{0,2}).*$

但是,即使找到的字符多于预期字符,它的计算结果也为true。限制器{2}似乎无效。

例如:mmddyyyymmmmmm将评估为true,即使其中有多个m。我不明白。

预期结果是只有诸如以下的组合才能测试为真:

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

而不是类似的东西

ddyyyyymmmmmmmmm
mmddyymm

请帮助我更正RegEx。

1 个答案:

答案 0 :(得分:2)

通常,匹配一个只能匹配包含允许块的字符串的字符串,然后使用某种编程方法来完成其余的“计数”工作(您只需检查有多少mm,{ {1}}或dd / yyyy)。

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

解决方案1:枚举所有替代方案

这是最不舒适,不是动态/不可扩展的解决方案,您只需将所有可能的模式收集到一个组中即可

yy

请参见this issue in the SAM repo^(?: [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:动态方法

此方法意味着匹配仅由三个$DM块组成的字符串,并使用正向先行限制模式,该正向先行将要求字符串仅包含单个每个块的发生。瓶颈和问题在于,这些块是多字符字符串,因此您需要使用regex demo(或将其解包,使正则表达式更加怪异):

Y

请参见tempered greedy token

因此,这里的^ (?=(?:(?![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} $ 部分从头到尾重复了3次,因此该字符串可以包含(?:[mM]{2}|[dD]{2}|[yY]{2}(?:[yY]{2})?)(?:[_-](?!$))?dy的三个出现,甚至如果它们相同(m也将匹配)。前瞻全部为mmmmmm的形式-仅当存在除BLOCK之外的任何文本,然后是BLOCK以及然后除BLOCK之外的任何文本为止,才匹配,直到字符串的结尾。