我正在尝试验证xs:duration,然后将其转换为秒。目前,这就是我所拥有的:
/P^([-])?(([\d.]*)Y)?(([\d.]*)M)?(([\d.]*)D)?T?(([\d.]*)H)?(([\d.]*)M)?(([\d.]*)S)?/
但是,不拒绝这些无效值(取自here):
P-20M
负号必须首先出现P20MT
没有时间项,因此“ T”一定不能存在P1YM5D
几个月没有指定值,因此“ M”一定不能为
礼物我想念什么?
我发现了类似的问题here,但该正则表达式仅适用于Python。
答案 0 :(得分:1)
您遗漏了几个要点,只需查看故障案例的描述即可轻松解决。以下正则表达式适用于所有情况(和失败情况),请参见Regex 101
^(-?)P(?=.)((\d+)Y)?((\d+)M)?((\d+)D)?(T(?=.)((\d+)H)?((\d+)M)?(\d*(\.\d+)?S)?)?$
首先,查看P15.5Y only the seconds can be expressed as a decimal
。您可以在任何地方使用[\d.]*
,这可以在任何地方使用一个或多个数字或点。但是只允许秒包含一个点,并且该点后必须跟一个数字。因此,将秒更改为(\d*(\.\d+)?S)
,将所有其他秒更改为(\d+Y)
(依此类推)。
此外,字符串需要以可选的-
开头,然后以P
开头,因此使用:
^-?P
然后,P
之后必须有一些内容,只需为此使用前瞻性断言:
(?=.)
然后,如前所述,出现Y
,M
和D
。
如果有时间因素,现在必须有一个T
,所以如果有其他情况,请确保我们有一个T
:
(T(?=.))
...并且仅当我们拥有T
时,我们才可以拥有H
,M
或S
:
(T(?=.)(\d+H)?(\d+M)?(\d*(\.\d+)?S)?)
先行断言可确保我们找到一些东西,其余部分捕获HMS部分。