我建立一个SCORM 2004为LMS的JavaScript API和SCORM的一个2004年的要求是,传递给它timeintervals必须遵循以下格式。 有谁知道这个正则表达式会是什么? 我想总结我的脑海围绕它,但无济于事。 注:P必须始终是第一个字符。
P [YY] [MM] [日] [T [HH] [nm]的[S [.S] S]]其中:
- Y:年数(> = 0的整数,没有限制)
- 米:月数(> = 0的整数,没有限制)
- d:天数(整数,> = 0,没有限制)
- H:的小时数(> = 0的整数,没有限制)
- N:的分钟数(> = 0的整数,没有限制)
- S:秒的秒部分的数量或(真实的或整数,> = 0,没有限制)。 如果使用几分之一秒,SCORM进一步限制了串到最大2位数字(例如,34.45 - 有效,34.45454545 - 无效)。
- 的字符文字标志符如果对应的非零值存在P,Y,M,d,T,H,M和S应当出现。
- 值的零填充应予支持。 零填充不改变数的整数值通过一组字符被表示。 例如,PT05H相当于PT5H和PT000005H。
例如 -
- P1Y3M2DT3H表示周期为1年,3个月,?? 2天到3小时
- PT3H5M指示周期的3小时和5分钟的时间里
任何帮助将不胜感激。
谢谢!
更新:
我已经补充说,必须保持一些额外的标准 -
- 标志符P应是本
- 如果年,月,日,时,分或秒中的值为零,则该值与相应的字符文字指定可以被省略,但至少有一个字符文字标志和值应除了标志P为本
- 如果所有的时间分量(小时,分和秒)的未使用标志符Ť将被省略。 零值可与任何时间的成分的使用(例如,PT0S)
下面是我使用正则表达式;
^P(?=\w*\d)(?:\d+Y|Y)?(?:\d+M|M)?(?:\d+D|D)?(?:T(?:\d+H|H)?(?:\d+M|M)?(?:\d+(?:\.\d{1,2})?S|S)?)?$
使用[0-9]
匹配任何数字。 +
匹配1个或多个重复。 ?
匹配0或1次重复。 ()
至组,并提取输出。
P(([0-9]+Y)?([0-9]+M)?([0-9]+D)?)(T([0-9]+H)?([0-9]+M)?([0-9.]+S)?)?
import re
>>> p = re.compile('P(([0-9]+Y)?([0-9]+M)?([0-9]+D)?)(T([0-9]+H)?([0-9]+M)?([0-9.]+S)?)?')
>>> p.match('P1Y3M2DT3H').groups()
('1Y3M2D', '1Y', '3M', '2D', 'T3H', '3H', None, None)
>>> p.match('P3M2DT3H').groups()
('3M2D', None, '3M', '2D', 'T3H', '3H', None, None)
>>> p.match('PT3H5M').groups()
('', None, None, None, 'T3H5M', '3H', '5M', None)
>>> p.match('P1Y3M4D').groups()
('1Y3M4D', '1Y', '3M', '4D', None, None, None, None)
JavaScript不支持/x
(自由间隔或注释模式),因此,使用它之前从这个表达式中删除空格。
/^P(?=.)
(?:\d+Y)?
(?:\d+M)?
(?:\d+D)?
(?:T(?=.)
(?:\d+H)?
(?:\d+M)?
(?:\d+
(?:\.\d{1,2})?
)?
)?$/i
每个(?=.)
预测先行断言,有留在在比赛中这一点至少一个字符。 这意味着下列基团(即,Y,M,d或者P后T组,以及H,M或S基团后T)具有相匹配,即使它们都是任选的至少一种。 满足的你的最新规范的要求添加第二。
也许是语义,但SCORM规范的这部分可以解释为文字被允许即使值未提供:
的字符文字标志符如果对应的非零值存在P,Y,M,d,T,H,M和S应当出现。
“应出现”意思是立即数必须存在,如果相应的数字存在; 它并没有说“应只出现”,如果相应的数字是存在的。
我修改Alan的正则表达式来处理这种可能性(感谢,阿兰):
^P(?:\d+Y|Y)?(?:\d+M|M)?(?:\d+D|D)?(?:T(?:\d+H|H)?(?:\d+M|M)?(?:\d+(?:\.\d{1,2})?S|S)?)?$
我到目前为止发现的唯一的错误是未能标志,有没有指定的数值,如“PTS”的字符串。 根据该规范,最小值为“P”,然后单个值和伴随的指定,如P1Y(= 1年)或PT0S(= 1秒):
至少一个字符文字标志和值应除了标志P为本
必须有添加一个检查的数值,这个正则表达式的方式,但我的正则表达式福不是强。 :)
对于它的价值,我已经适应了用冷聚变使用公认的答案。 我想有些人可能会发现它很有用,所以我想我会张贴。 如上所述,CF轰炸上秒以上实施,所以我修改它。 我不知道如果这意味着它在上面的例子中的通用正则表达式的错误,或者CF和JS有不同的正则表达式的实现。 总之,这里的CF正则表达式,完整的意见(因为,你知道,否则正则表达式是完整的胡言乱语):
<cfset regex = "(?x) ## allow for multi-line expression, including comments (oh, glorious comments)
^ ## ensure that this expression occurs at the start of the string
P ## the first character must be a P
(\d+Y|Y)? ## year (the ? indicates 0 or 1 times)
(\d+M|M)? ## month
(\d+D|D)? ## day
(?:T ## T delineates between day and time information
(\d+H|H)? ## hour
(\d+M|M)? ## minute
(\d+(?:\.\d{1,2})?S|S)? ## seconds and milliseconds. The inner ?: ensure that the sub-sub-expression isn't returned as a separate thing
)? ## closes 'T' subexpression
$ ## ensure that this expression occurs at the end of the string. In conjunction with leading ^, this ensures that the string has no extraenous characters">
在这之后,你运行它针对您的字符串是这样的:
<cfset result = reFind(regex,mystring,1,true)>
返回子表达式,你可以遍历得到离散零件组成的数组:
<cfloop from=1 to=#arrayLen(result.len)# index=i>
<cfif result.len[i] GT 0>
#mid(mystring, result.pos[i], result.len[i])#<br>
</cfif>
</cfloop>
我们SCORM Engine实现使用类似于上述的那些和一些基本的JavaScript逻辑也做了进一步的验证正则表达式的组合。
我使用这个表达式:
^P(\d+Y)?(\d+M)?(\d+D)?(T(((\d+H)(\d+M)?(\d+(\.\d{1,2})?S)?)|((\d+M)(\d+(\.\d{1,2})?S)?)|((\d+(\.\d{1,2})?S))))?$
这种表达不匹配,如“PYMDT0H”的值:一个数字必须陪标志进行匹配。
根据先前接受的答案,我做了这捕获正则表达式PCRE(PHP,红宝石,EcmaScript的2018年,...): https://regex101.com/r/KfMs1I/6
^P (?=\w*\d) (?:(?<years>\d+)Y|Y)? (?:(?<month>\d+)M|M)? (?:(?<days>\d+)D|D)? (?: T (?:(?<hours>\d+)H|H)? (?:(?<minutes>\d+)M|M)? (?: (?<seconds> \d+ (?: \. \d{1,2} )? )S | S )? )?$
不幸的是我无法找到如何做到在当前JS一样的,因为可选的组不能可靠地没有命名组访问。