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 应出现
- 如果年、月、日、小时、分钟或秒的值为 零,该值和对应的 字符字面指定可能是 省略,但至少有一个字符 文字指示符和值应为 除了指示符之外还存在
- 如果所有时间组成部分(小时、 分钟和秒)不被使用。一个 零值可以与任何一个一起使用 时间组件(例如PT0S)
I am building a SCORM 2004 javascript API for an LMS, and one of the SCORM 2004 requirements is that timeintervals passed into it must follow the following format. Does anyone know what the regular expression of this would be? I am trying to wrap my mind around it, but to no avail. Note: P must always be the first character.
P[yY][mM][dD][T[hH][nM][s[.s]S]]
where:
- y: The number of years (integer, >= 0, not restricted)
- m: The number of months (integer, >=0, not restricted)
- d: The number of days (integer, >=0, not restricted)
- h: The number of hours (integer, >=0, not restricted)
- n: The number of minutes (integer, >=0, not restricted)
- s: The number of seconds or fraction of seconds (real or integer, >=0, not
restricted). If fractions of a second are used, SCORM further restricts the string to
a maximum of 2 digits (e.g., 34.45 – valid, 34.45454545 – not valid).- The character literals designators P, Y, M, D, T, H, M and S shall appear if the
corresponding non-zero value is present.- Zero-padding of the values shall be supported. Zero-padding does not change the
integer value of the number being represented by a set of characters. For
example, PT05H is equivalent to PT5H and PT000005H.Example -
- P1Y3M2DT3H indicates a period of time of 1 year, 3 months, 2 days and 3
hours- PT3H5M indicates a period of time of 3 hours and 5 minutes
Any help would be greatly appreciated.
Thanks!
UPDATE:
I have added some additional standards that must be kept -
- The designator P shall be present
- If the value of years, months, days, hours, minutes or seconds is
zero, the value and corresponding
character literal designation may be
omitted, but at least one character
literal designator and value shall be
present in addition to the designator
P- The designator T shall be omitted if all of the time components (hours,
minutes and seconds) are not used. A
zero value may be used with any of the
time components (e.g., PT0S)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
这是我使用的正则表达式;
Here is the regex i use;
使用
[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)?)?
Use
[0-9]
to match any numeral.+
to match 1 or more repetitions.?
to match 0 or 1 repetitions.()
to group and extract the output.P(([0-9]+Y)?([0-9]+M)?([0-9]+D)?)(T([0-9]+H)?([0-9]+M)?([0-9.]+S)?)?
JavaScript 不支持
/x
(自由间距或注释模式),因此请在使用此正则表达式之前删除空格。每个
(?=.)
前瞻断言匹配中的该点至少还剩下一个字符。这意味着至少以下组之一(即 P 之后的 Y、M、D 或 T 组,以及 T 之后的 H、M 或 S 组)必须匹配,即使它们都是可选的。这满足了更新规范中第二个添加的要求。JavaScript doesn't support
/x
(free-spacing or comments mode), so remove the whitespace from this regex before using it.Each
(?=.)
lookahead asserts that there's at least one character remaining at that point in the match. That means at least one of the following groups (ie, the Y, M, D or T group after the P, and the H, M or S group after the T) has to match, even though they're all optional. That satisfies the second of the added requirements in your updated spec.就其价值而言,我已经调整了已接受的答案以与冷聚变一起使用。我想有些人可能会觉得它有用,所以我想我会发布它。如上所述,CF 轰炸了上面的秒实现,所以我修改了它。我不确定这是否意味着上面示例中的常规正则表达式错误,或者 CF 和 JS 是否有不同的正则表达式实现。无论如何,这是 CF RegEx,带有注释(因为,你知道,否则正则表达式完全是胡言乱语):
之后,你对你的字符串运行它,如下所示:
返回一个子表达式数组,你可以迭代它来获取离散部分:
For what it's worth, I've adapted the accepted answer for use with Cold Fusion. I thought some folks might find it useful, so I figured I'd post it. As noted above, CF bombed on the seconds implementation above, so I modified it. I'm not sure if that means it's a general RegEx error in the above example, or if CF and JS have different RegEx implementations. Anyway, here's the CF RegEx, complete with comments (because, you know, otherwise regular expressions are complete gibberish):
After that, you run it against your string like this:
That returns an array of subexpressions, which you can iterate over to get the discreet parts:
我们的 SCORM 引擎实现使用与上面类似的正则表达式的组合,并且一些基本的 JavaScript 逻辑确实进行了进一步的验证。
Our SCORM Engine implementation uses a combination of a regular expression similar to the ones above and some basic JavaScript logic do do further validation.
也许这是语义上的问题,但是 SCORM 规范的这一部分可以解释为即使未提供值也允许使用文字:
“应出现”意味着如果对应的数字存在,则文字必须存在;如果存在相应的数字,它并没有说“仅应出现”。
我修改了艾伦的正则表达式来处理这种可能性(谢谢,艾伦):
到目前为止我发现的唯一错误是无法标记未指定数值的字符串,例如“PTS”。根据规范,最小值为“P”,后跟单个值和随附名称,例如 P1Y(= 1 年)或 PT0S(= 1 秒):
还必须有一种方法可以向此正则表达式添加对数值的检查,但我的 regex-fu 不是那么强大。 :)
Maybe it's semantics, but this part of the SCORM spec can be interpreted to mean literals are allowed even if a value isn't supplied:
"shall appear" meaning a literal MUST be present if the corresponding number is present; it doesn't say "shall ONLY appear" if the corresponding number is present.
I modified Alan's regex to handle this possibility (thanks, Alan):
The only bug I've found so far is a failure to flag a string that has no numeric values specified, such as 'PTS'. The minimum according to the spec is "P" followed by a single value and accompanying designation, such as P1Y (= 1 year) or PT0S (= 1 second):
There must be a way to add a check for a numeric value to this regex, but my regex-fu is not that strong. :)
我正在使用这个表达式:
此表达式与“PYMDT0H”之类的值不匹配:数字必须伴随指示符才能匹配。
I'm using this expression:
This expression does not match a value like "PYMDT0H" : a digit must accompany the designator to be matched.
根据之前接受的答案,我为PCRE(PHP,ruby,Ecmascript 2018,...)制作了这个捕获正则表达式: https://regex101.com/r/KfMs1I/6
^P
(?=\w*\d)
(?:(?<年>\d+)Y|Y)?
(?:(?<月份>\d+)M|M)?
(?:(?<天数>\d+)D|D)?
(?:
时间
(?:(?<小时>\d+)H|H)?
(?:(?<分钟>\d+)M|M)?
(?:
(?<秒>;
\d+
(?:
\.
\d{1,2}
)?
)S
|
S
)?
)?$
不幸
的是,我无法找到如何在当前的 JS 中执行相同的操作,因为如果没有命名组,则无法以可靠的方式访问可选组。
Based on the previously accepted answer, I've made this capturing regex for 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
)?
)?$
Unfortunately I can't find how to do the same in current JS, because the optional groups cannot be accessed in a reliable way without named groups.