我真的不完全理解regex的条件特性的概念。至少我没有让它工作。所以我想匹配下面的字符串
28.11 16.12
"13.01 23,09"
01.08.-31.12
"01.01,-51.12"
"01,01.-31,12."
01083112
1.02 - 4.3
使用以下正则表达式
\D*(?P<from_day>[12]\d|3[01]|0?[1-9])[.\s,■\-]*
(?P<from_month>1[0-2]|0?[1-9])[.\s,■\-]*
(?P<until_day>[12]\d|3[01]|0?[1-9])[.\s,■\-]*
(?P<until_month>1[012]|0?[1-9]).*|.+
它工作正常,但现在我也想接受2811 16.12
或28.11 16.12
,但不接受2811 1612
或28111612
,因此最多4位数字之间应该有一个分隔符。
我尝试了一个更简单的正则表达式https://regex101.com/r/j5JL0u/1,但我没有得到它的工作。
2条答案
按热度按时间gopyfrb31#
如果您想将这些完整的行与命名的捕获组匹配,您可以使用正向前查找来Assert一个“分隔符”,而不是一个空白字符(注意
\s
也可以匹配一个换行符)2 - 4位。锚点
^
和$
Assert字符串的开始和结束。字符串
"01.01,-51.12"
不匹配,因为当前模式也不匹配51
字符串
01083112
不匹配,因为没有分隔符。^
字符串开头"?
匹配可选"
(?=.*\b\d\d?[.\s,■\-]\d\d?\b)
正向预测,Assert2 - 4位之间的[.\s,■\-]
之一。字边界\b
防止部分字匹配。(?P<from_day>[12]\d|3[01]|0?[1-9])[.\s,■\-]*(?P<from_month>1[0-2]|0?[1-9])
* from_day * 和 * from_month * 模式[.\s,■\-]*
可选重复匹配[.\s,■\-]
之一(?P<until_day>[12]\d|3[01]|0?[1-9])[.\s,■\-]*(?P<until_month>1[012]|0?[1-9])
* until_day * 和 * until_month * 模式`[.\s,■\-]*
匹配允许的可选尾随字符"?
$
字符串结束请参见regex demo。
yuvru6vn2#
我知道这不能完全满足要求;我只是提供答案作为起点,或参考,可能提供某种洞察力的解决方案。
这将与您提供的值 01083112 相矛盾。
考虑到模式的复杂性,我建议在程序中评估捕获的值,而不是在模式中。
以下代码将捕获这些值,01083112 除外。
和你的命名组。
如果你想检查模式中的所有条件,那么不一定需要条件语句。
您使用的当前方法是正确的,在该方法中,您根据特定的月份值检查日期。
在regex中,这是实现这一点的典型方法。
注意,因为它们是日期值,所以会有闰年。
所以,你还必须检查2月的 29 天。
作为参考,IPv4地址 * 有效性有时用类似的概念来实现。
这是下一本书,O'Reilly Media – Regular Expressions Cookbook – 7.16. Matching IPv4 Addresses *。