匹配可选部分的部分

时间:2013-09-27 18:11:32

标签: 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场比赛?

3 个答案:

答案 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]ap匹配,由于ampm都以m结尾,因此您只需使用[ap]m和不区分大小写的修饰符使[ap]m匹配大写和小写字符。

答案 2 :(得分:2)

Group时间并将其optional

/(\d{1,2})\/(\d{1,2})\/(\d{2,4})(?: (\d{1,2}):(\d{1,2})(am|pm|AM|PM|Am|Pm))?/

?:会抑制捕获,因此如果时间存在,您不会再使用其他组。

此外,如果您对允许aMpM不太挑剔,可以使用不区分大小写的修饰符大大简化:

/(\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"]