正则表达式为ISO 8601持续时间

时间:2015-08-17 07:26:10

标签: regex dateinterval

我需要一个正则表达式来验证ISO 8601 duration format中的持续时间(除了我不需要的小数部分)。

  

PnYnMnDTnHnMnS

     

PNW

这就是我所拥有的:

^P(\d+Y)?(\d+M)?(\d+W)?(\d+D)?(T(\d+H)?(\d+M)?(\d+S)?)?$

唯一的问题是此正则表达式允许使用字符串PPT,因为所有部分都是“零或一”?

  • 至少需要一个组件(日期或时间)
  • 如果有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'来提供帮助,但遗憾的是并非如此。

4 个答案:

答案 0 :(得分:18)

如果你几乎所有部分都是可选的,但你想确保在PT之后还有别的东西,你可以使用预测:

^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)$

干杯!