匹配部分的可选部分
我有一个正则表达式设置为匹配US格式的日期和时间。它看起来像这样:匹配部分的可选部分
/(\d{1,2})\/(\d{1,2})\/(\d{2,4}) (\d{1,2}):(\d{1,2})(am|pm|AM|PM|Am|Pm)/
但是,我需要它也匹配日期,不包含时间组件。
如何修改这一点,因此,如果它是一个日期,我得到的3场比赛,如果它是一个日期 - 时间,我送六?
/(\d{1,2})\/(\d{1,2})\/(\d{2,4})(?: (\d{1,2}):(\d{1,2})(am|pm|AM|PM|Am|Pm))?/
的?:
抑制拍摄,让你不附加组结束了,如果时间存在。
另外,如果你不是太挑剔允许aM
和pM
,你可以用相当不区分大小写的修改简化:
/(\d{1,2})\/(\d{1,2})\/(\d{2,4})(?: (\d{1,2}):(\d{1,2})([ap]m))?/i
事实上,使用?
你甚至可以缩短图形另外, (因为\d?
短于{1,2}
:
/(\d\d?)\/(\d\d?)\/(\d{2,4})(?: (\d\d?):(\d\d?)([ap]m))?/i
不过请注意,在任何情况下,你仍然会得到6组(7如果算上整个匹配) - 这是菊ST,最后三会undefined
:
> groups = '11/11/11'.match(/(\d{1,2})\/(\d{1,2})\/(\d{2,4})(?: (\d{1,2}):(\d{1,2})([ap]m))?/i)
["11/11/11", "11", "11", "11", undefined, undefined, undefined]
同样使用exec
代替时发生。但这些都是容易的,如果需要过滤掉:
> groups.filter(function(capture) {
return typeof capture !== 'undefined';
});
["11/11/11", "11", "11", "11"]
或在此情况下(因为你永远不能拥有空字符串作为捕获):
> groups.filter(function(capture) {
return capture;
});
["11/11/11", "11", "11", "11"]
使用?
时间正则表达式,包装与(?:)
非捕获组。
/(\d{1,2})\/(\d{1,2})\/(\d{2,4})(?:\s+(\d{1,2}):(\d{1,2})(am|pm|AM|PM|Am|Pm))?/
请注意,文字空间已被替换为\s+
。
+
- 匹配1个或多个
*
- 匹配0个或更多
?
- 匹配0或1
您可以使用此:
/(\d{1,2})\/(\d{1,2})\/(\d{2,4})(?: (\d{1,2}):(\d{1,2})(am|pm|AM|PM|Am|Pm))?/
甚至缩短您的正则表达式:
/(\d{1,2})\/(\d{1,2})\/(\d{2,4})(?: (\d{1,2}):(\d{1,2})([ap]m))?/i
我包裹的空间和时间成非捕获组,把一个用于?
0或1次发生,使时间可选的。
的字符类[ap]
比赛无论是a
或p
以来都am
和pm
结束与m
,你可以简单地使用[ap]m
和不区分大小写的修改,使[ap]m
匹配大写和小写字符。
虽然没有更好的解决方案,但请注意,这不会产生只有4个元素的阵列。此外,你放弃捕获am/pm'位。 –
在缩短xD期间一定发生过谢谢! – Jerry
虽然没有更好的解决方案,请注意,这不会产生只有4个元素的数组。 –
4个要素?对不起,没有得到你。那问题在哪里? – jkshah
OP希望“只有3个匹配”,所以我认为值得指出的是,在'match'或'exec'中使用模式时,您获得的数组仍然具有相同数量的元素。只是它们中的一些将会是'未定义的'。 –