2

我设置了一个正则表达式来匹配美国格式的日期和时间。它看起来像这样:

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

但是,我还需要它来匹配不包含时间组件的日期。

我该如何修改它,如果是日期,我会得到 3 个匹配项,如果是日期时间,我会得到 6 个匹配项?

4

3 回答 3

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

于 2013-09-27T18:13:56.007 回答
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]匹配aorp和 ,因为amand都pm以 结尾m,您可以简单地使用[ap]mand 不区分大小写的修饰符来[ap]m匹配大写和小写字符。

于 2013-09-27T18:14:03.103 回答
2

将时间分组并使其可选

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

抑制捕获,因此?:如果时间存在,您最终不会得到额外的组。

aM此外,如果您对允许and不太挑剔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"]
于 2013-09-27T18:14:31.790 回答