我需要一个正则表达式来验证ISO 8601 duration format中的持续时间(除了我不需要的小数部分)。
PnYnMnDTnHnMnS
PNW
这就是我所拥有的:
^P(\d+Y)?(\d+M)?(\d+W)?(\d+D)?(T(\d+H)?(\d+M)?(\d+S)?)?$
唯一的问题是此正则表达式允许使用字符串P
和PT
,因为所有部分都是“零或一”?
。
T
则需要有时间成分(H,M或S)T
,则可能有也可能没有任何日期组件(Y,M或D)P72H
大致相当于P3D
)可接受的输入:
P1Y // date component only
P2MT30M // date and time components
PT6H // time component only
P5W // another date component
不可接受的输入:
P // no components
PT // no components
P3MT // T specified but not time components
现在无效字符串正在通过客户端验证但在服务器端失败,因为它已传递到DateInteval
但我想在可能的情况下在客户端失败。如果每个人都在使用Chrome 40+,我可以在输入元素上指定minlength='3'
来提供帮助,但遗憾的是并非如此。
答案 0 :(得分:18)
如果你几乎所有部分都是可选的,但你想确保在P
或T
之后还有别的东西,你可以使用预测:
^P(?=\d+[YMWD])(\d+Y)?(\d+M)?(\d+W)?(\d+D)?(T(?=\d+[HMS])(\d+H)?(\d+M)?(\d+S)?)?$
^^^^^^^^^^^^ ^^^^^^^^^^^^
它们需要一系列数字,后跟指定集合中的字母才会出现在前一个模式之后。
请参阅demo
<强>更新强>
如果P
可以为“空”,请使用
^P(?!$)(\d+Y)?(\d+M)?(\d+W)?(\d+D)?(T(?=\d+[HMS])(\d+H)?(\d+M)?(\d+S)?)?$
见another demo。在这里,(?!$)
确保字符串不等于P
,并且右侧必须有一些其他符号。
或者,正如@UlugbekUmirov建议的那样,它是enough to just use T(?=\d)
(因为所有可选部分都以数字开头):
^P(?!$)(\d+Y)?(\d+M)?(\d+W)?(\d+D)?(T(?=\d)(\d+H)?(\d+M)?(\d+S)?)?$
更新2
如果数字可以是浮点数或整数,请在每个(?:\.\d+)?
后添加\d+
。以下是Update 1的更新模式:
^P(?!$)(\d+(?:\.\d+)?Y)?(\d+(?:\.\d+)?M)?(\d+(?:\.\d+)?W)?(\d+(?:\.\d+)?D)?(T(?=\d)(\d+(?:\.\d+)?H)?(\d+(?:\.\d+)?M)?(\d+(?:\.\d+)?S)?)?$
答案 1 :(得分:3)
以上答案不包括小数点的情况(有关详细信息,请参见here)。小数部分可以出现在最后一个元素上。以下正则表达式包含小数部分:
^P(?!$)((\d+Y)|(\d+\.\d+Y$))?((\d+M)|(\d+\.\d+M$))?((\d+W)|(\d+\.\d+W$))?((\d+D)|(\d+\.\d+D$))?(T(?=\d)((\d+H)|(\d+\.\d+H$))?((\d+M)|(\d+\.\d+M$))?(\d+(\.\d+)?S)?)??$
有关测试,请参见here。
答案 2 :(得分:0)
以上答案需要附加的后处理。
import_id_fields = ('user__username')
输出:
import_id_fields = ('user__username', )
答案 3 :(得分:0)
如果您要搜索包含开始日期的正则表达式 和持续时间,请检查以下内容:
^(\d{4}(-\d{2}(-\d{2})?(?!:))?(T\d{2}(:\d{2}(:\d{2})?(\.\d+)?)?)?(Z|([+,-]\d{2}(:\d{2})?))?)?P(([0-9]+([.,][0-9]*)?Y)?([0-9]+([.,][0-9]*)?M)?([0-9]+([.,][0-9]*)?D)?T?([0-9]+([.,][0-9]*)?H)?([0-9]+([.,][0-9]*)?M)?([0-9]+([.,][0-9]*)?S)?)|\d{4}-?(0[1-9]|11|12)-?(?:[0-2]\d|30|31)T((?:[0-1][0-9]|[2][0-3]):?(?:[0-5][0-9]):?(?:[0-5][0-9]|60)|2400|24:00)$
干杯!