regex - RegEx 日期模式格式验证未按预期工作
问题描述
我正在尝试验证日期格式输入。输入不是实际日期,而是D
M
Y
输入。而且我不想验证实际日期!只是格式。
我想用或分隔符评估任何使用 double D
、 double M
、 double 或 quadruple完成的输入。Y
-
_
我当前的 RegEx 如下所示:
^(?=.*[mM]{2})(?=.*[dD]{2})(?=.*[yY]{2,4})(?=.*[-_]{0,2}).*$
但是,即使找到的字符多于预期字符,这也会评估为真。限制器{2}
似乎没有效果。
例如:mmddyyyymmmmmm
即使那里有多个m
,也会评估为真。我不明白。
预期的结果是只有如下组合才能测试为真:
dd-mm-yy
MM-DD_YYYY
yyyy_dd-MM
mmddyy
YYYYddMM
而不是这样的:
ddyyyyymmmmmmmmm
mmddyymm
请帮我纠正我的正则表达式。
解决方案
通常,匹配一个只能匹配包含允许块的字符串的字符串是有意义的,然后使用一些编程手段来完成其余的“计数”工作(您只需检查有多少mm
,dd
或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:动态方法
这种方法意味着匹配仅由三个D
、M
或Y
块组成的字符串,并使用正向前瞻来限制模式,这将要求字符串仅包含每个块的一次出现。瓶颈和问题在于块是多字符串,因此您需要使用经过调和的贪婪令牌(或打开它,使正则表达式更加怪异):
^
(?=(?:(?![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 次,因此,字符串可以包含 3 次出现d
,y
或m
,即使它们相同(mmmmmm
也将匹配)。前瞻的形式都是(?=(?:(?!BLOCK).)*BLOCK(?:(?!BLOCK).)*$)
- 仅当存在除 BLOCK 之外的任何文本时才匹配,然后是 BLOCK,然后是除 BLOCK 之外的任何文本,直到字符串的末尾。
推荐阅读
- java - 尝试通过 JSTL 表单标签提交表单时收到错误“bean 类的无效属性 'xxx'”
- python - 每次元素更改时如何获取新列表(该元素是元组列表中每个元组的某个索引)
- google-cloud-datastore - 是否应该编写实体以确保不重用自动分配的 ID?
- javascript - 渲染后如何根据状态切换子组件?
- python - 属性错误:“模块‘numpy.random’没有属性‘uniform’”
- mariadb - 创建用户并撤销他们对 MariaDB 上特定数据库的访问权限
- ios - 我想通过我的 BLE 设备连接到 iPhone 的 BLE
- ios - 将应用程序上传到 iTunes 连接时如何解决 Xcode 验证错误?
- sql - 追加查询不追加缺失项
- python - 简单的神经网络误差先减小后增大