SCORM 2004时间格式 - 正则表达式?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SCORM 2004时间格式 - 正则表达式?相关的知识,希望对你有一定的参考价值。
我正在为LMS构建SCORM 2004 javascript API,SCORM 2004的一个要求是传入它的时间间隔必须遵循以下格式。有谁知道这个正则表达式是什么?我试图围绕它,但无济于事。注意:P必须始终是第一个字符。
P [yY] [mM] [dD] [T [hH] [nM] [s [.s] S]]其中:
- y:年数(整数,> = 0,不受限制)
- m:月数(整数,> = 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之外,还应存在至少一个字符文字指示符和值。
- 如果不使用所有时间组件(小时,分钟和秒),则应省略指示符T.零值可以与任何时间分量一起使用(例如,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
每个(?=.)
前瞻声明在比赛中至少有一个角色剩余。这意味着以下组中的至少一个(即,P之后的Y,M,D或T组,以及T之后的H,M或S组)必须匹配,即使它们都是可选的。这满足了您更新的规范中的第二个增加的要求。
也许它是语义,但SCORM规范的这一部分可以解释为即使没有提供值也允许文字:
如果存在相应的非零值,则应出现字符文字指示符P,Y,M,D,T,H,M和S.
“应出现”意味着如果存在相应的数字,则必须存在字面值;如果存在相应的数字,它不会说“仅出现”。
我修改了Alan的正则表达式来处理这种可能性(谢谢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之外,还应存在至少一个字符文字指示符和值
必须有一种方法可以为这个正则表达式添加一个数值检查,但我的正则表达式并不强大。 :)
为了它的价值,我已经采用了与Cold Fusion一起使用的可接受的答案。我以为有些人可能觉得它很有用,所以我想我会发布它。如上所述,CF轰炸了上面的秒实现,所以我修改了它。我不确定这是否意味着它是上述示例中的一般RegEx错误,或者CF和JS是否有不同的RegEx实现。无论如何,这是CF RegEx,带有注释(因为,你知道,否则正则表达式完全是胡言乱语):
<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,ruby,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中找到如何执行相同的操作,因为在没有命名组的情况下无法以可靠的方式访问可选组。
以上是关于SCORM 2004时间格式 - 正则表达式?的主要内容,如果未能解决你的问题,请参考以下文章