Javascript 匹配可选部分的各个部分
我设置了一个正则表达式来匹配美国格式的日期和时间。看起来是这样的:Javascript 匹配可选部分的各个部分,javascript,regex,Javascript,Regex,我设置了一个正则表达式来匹配美国格式的日期和时间。看起来是这样的: /(\d{1,2})\/(\d{1,2})\/(\d{2,4}) (\d{1,2}):(\d{1,2})(am|pm|AM|PM|Am|Pm)/ 但是,我还需要它匹配不包含时间组件的日期 我如何修改它,以便如果是日期,我得到3个匹配项,如果是日期时间,我得到6个匹配项?使用?环绕时间正则表达式,使用(?:)非捕获组包装 /(\d{1,2})\/(\d{1,2})\/(\d{2,4})(?:\s+(\d{1,2}):(\d{1,
/(\d{1,2})\/(\d{1,2})\/(\d{2,4}) (\d{1,2}):(\d{1,2})(am|pm|AM|PM|Am|Pm)/
但是,我还需要它匹配不包含时间组件的日期
我如何修改它,以便如果是日期,我得到3个匹配项,如果是日期时间,我得到6个匹配项?使用
?
环绕时间正则表达式,使用(?:)
非捕获组包装
/(\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
匹配大小写字符。时间并使其:
?:
禁止捕获,这样,如果有时间,您就不会得到额外的组
此外,如果您对允许使用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组)-只是最后三组将是未定义的:
> 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"]
或者在这种情况下(因为您永远不能将空字符串作为捕获):
虽然没有更好的解决方案,但请注意,这不会生成只有4个元素的数组。此外,您放弃了捕获am/pm
位。一定是在缩短xD期间发生的。谢谢!虽然没有更好的解决方案,但请注意,这不会生成只有4个元素的数组。4个元素?抱歉,没有理解您。whe有问题吗?OP需要“仅3个匹配”,因此我认为值得指出的是,在match
或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"]