我一生似乎无法弄清楚如何使用格式设置元素的正则表达式。
1d 5h 6m 12s
并且还允许它有任何变化,例如
1d
1d 1h
1d 1h 1m
1d 1s
6m 12s
etc...
是否可以使用正则表达式进行这种格式设置?
我一生似乎无法弄清楚如何使用格式设置元素的正则表达式。
1d 5h 6m 12s
并且还允许它有任何变化,例如
1d
1d 1h
1d 1h 1m
1d 1s
6m 12s
etc...
是否可以使用正则表达式进行这种格式设置?
假设您需要订购,
if (/^\s*(?:(?:[1-9]\d*|0)d\s+)?(?:(?:1?\d|2[0-3])h\s+)?(?:[1-5]?\dm\s+)?(?:[1-5]?\ds)?\s*$/.test(str))
{
// success
}
这是一个快速细分:
和^
被$
称为锚点。它们匹配字符串的开头和结尾,因此您匹配的是整个字符串,而不仅仅是一部分,否则 hello, world! 1d 5h 6m 12s
会通过。
\s*
and\s+
匹配零个或多个,以及一个或多个空白字符。
(?:[1-9]\d*|0)
匹配任意数量的数字,但不匹配以零开头的数字,除非它正好为零。
(?:1?\d|2[0-3])
匹配 0 到 23 之间的数字,包括 0 和 23 。
[1-5]?\d
匹配 0 到 59 之间的数字,包括 0 和 59 。
这些(?: ... )
被称为非捕获组。它们就像括号(用于分组),除了普通的 ol' 括号capture,我们在这里不需要。
?
表示前面的实体是可选的。
给你一个起点:
(\d+d){0,1} //days - not checking for a max
(((([0-1]){0,1}\d)|(2[0-4]))h){0,1} // 24 hours
(((([0-5]){0,1}[0-9])|(60))m){0,1} //60 minutes
(((([0-5]){0,1}[0-9])|(60))s){0,1} //60 seconds
然后把它们放在一起(在这种情况下不用担心空格的数量)
(\d+d){0,1}[ ]*(((([0-1]){0,1}\d)|(2[0-4]))h){0,1}[ ]*(((([0-5]){0,1}[0-9])|(60))m){0,1}[ ]*(((([0-5]){0,1}[0-9])|(60))s){0,1}[ ]*
从评论中包括@nhahtdh 的上述改进版本。谢谢!
((\d+)d)? *(([01]?\d|2[0-4])h)? *(([0-5]?\d|60)m)? *(([0-5]?\d|60)s)? *
我认为这就是你想要的:
function parse(s) {
y = s.match(/(?:(\d+)d\s*)?(?:(\d+)h\s*)?(?:(\d+)m\s*)?(?:(\d+)s)?/);
console.log(y);
return y;
}
以下是它的工作原理:
(\d+)d\s*
匹配一些后跟 a 的数字d
,后跟可选的空格(?:...)?
,就像(?:(\d+)d\s*)?
使上述内容成为可选的一样。这?:
导致新的括号集不是捕获组。