SCORM 2004时间格式 - 正则表达式?

问题描述 投票:6回答:8

我正在为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)
regex time scorm
8个回答
5
投票

这是我使用的正则表达式;

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

1
投票

使用[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)

1
投票

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组)必须匹配,即使它们都是可选的。这满足了您更新的规范中的第二个增加的要求。


1
投票

也许它是语义,但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之外,还应存在至少一个字符文字指示符和值

必须有一种方法可以为这个正则表达式添加一个数值检查,但我的正则表达式并不强大。 :)


1
投票

为了它的价值,我已经采用了与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>

0
投票

我们的SCORM Engine实现使用类似于上面的正则表达式的组合,并且一些基本的JavaScript逻辑做了进一步的验证。


0
投票

我正在使用这个表达式:

^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”之类的值不匹配:数字必须与指定符匹配。


0
投票

基于之前接受的答案,我已经为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中找到如何执行相同的操作,因为在没有命名组的情况下无法以可靠的方式访问可选组。

© www.soinside.com 2019 - 2024. All rights reserved.