我设置了正则表达式,以匹配美国格式的日期和时间。它看起来像这样:
/(\d{1,2})\/(\d{1,2})\/(\d{2,4}) (\d{1,2}):(\d{1,2})(am|pm|AM|PM|Am|Pm)/
但是,我还需要它来匹配不包含时间组件的日期。
如何修改此项,如果是日期,我会获得3场比赛,如果是日期时间,我会获得6场比赛?
答案 0 :(得分:2)
在时间正则表达式周围使用?
,使用(?:)
非捕获组包装。
/(\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
答案 1 :(得分:2)
您可以使用:
/(\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
匹配大写和小写字符。
答案 2 :(得分:2)
/(\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组) - 只是最后三组将是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"]