使用分数验证ISO 8601持续时间字符串。

3
这可能有点棘手,我正在尝试设计一个正则表达式来验证各种给定的日期间隔是否符合8601规范(https://en.wikipedia.org/wiki/ISO_8601#Durations)。我已经使用以下正则表达式使几乎所有情况都能正常工作:

^P(\d+(?:[,.]\d+)?Y)?(\d+(?:[,.]\d+)?M)?(\d+(?:[,.]\d+)?D)?(?:T(\d+(?:[,.]\d+)?H)?(\d+(?:[,.]\d+)?M)?(\d+(?:[,.]\d+)?S)?)?$

然而,它的缺点在于小数单位只允许在最小提供的单位上使用。例如,P1DT1.5H是有效的字符串(上述正则表达式在技术上允许这种情况),但P1.5DT1H不是有效的持续时间,因为小时是最小提供的单位,P1.5DT1.5H也无效。我已经达到了我的正则表达式技能的极限,无法想出一种将其纳入上述内容中的方法。是否有人能够提供帮助或指导,以实现这个目标?

1
我们可以假设小数部分只有在右侧没有更多数字时才会出现吗?请尝试使用 ^P(?!.*\d\.\d.*\d)(?!$)(\d+(?:\.\d+)?Y)?(\d+(?:\.\d+)?M)?(\d+(?:\.\d+)?W)?(\d+(?:\.\d+)?D)?(T(?=\d)(\d+(?:\.\d+)?H)?(\d+(?:\.\d+)?M)?(\d+(?:\.\d+)?S)?)?$。请参见 https://regex101.com/r/pv3922/2 - Wiktor Stribiżew
搞定了。我稍微修改了一下,这样逗号也可以用作小数符号。但是太棒了,非常感谢。所以最终版本看起来像这样: ^P(?!.*\d[,.]\d.*\d)(?!$)(\d+(?:[,.]\d+)?Y)?(\d+(?:[,.]\d+)?M)?(\d+(?:[,.]\d+)?W)?(\d+(?:[,.]\d+)?D)?(T(?=\d)(\d+(?:[,.]\d+)?H)?(\d+(?:[,.]\d+)?M)?(\d+(?:[,.]\d+)?S)?)?$ - Kussie
1个回答

1

假设小数部分只能在右侧没有更多数字的情况下出现,您可以使用

^P(?!.*\d[,.]\d.*\d)(?!$)(\d+(?:[,.]\d+)?Y)?(\d+(?:[,.]\d+)?M)?(\d+(?:[,.]\d+)?W)?(\d+(?:[,.]\d+)?D)?(T(?=\d)(\d+(?:[,.]\d+)?H)?(\d+(?:[,.]\d+)?M)?(\d+(?:[,.]\d+)?S)?)?$

请查看正则表达式演示

(?!.*\d[,.]\d.*\d)负向先行断言会在字符串中有带小数部分的数字后面跟着另一个数字时匹配失败。

您可以在ISO 8601持续时间的正则表达式文章中了解更多使用的模式。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接