正则表达式:非数字中的非捕获组?

时间:2016-01-12 15:10:23

标签: regex

我正在尝试测试时间戳(让我们使用HH:MM:ss作为示例)周围没有任何数字字符,或者说我想检查一下在我的时间戳之前和之后存在非数字字符。非数字字符不需要存在,但不应该在之前或之后直接存在数字字符。我不想捕获这个非数字字符。我怎样才能做到这一点?我应该使用"环顾四周"或非捕获组?

填写空白 + (2[0-3]:[0-5][0-9]:[0-5][0-9]|[0-1][0-9]:[0-5][0-9]:[0-5][0-9]) + 填写空白

谢谢!

2 个答案:

答案 0 :(得分:2)

“非数字的任何东西”的正则表达式类是:

\D

is equivalent to

[^\d]

所以你会使用:

\D*(2[0-3]:[0-5][0-9]:[0-5][0-9]|[0-1][0-9]:[0-5][0-9]:[0-5][0-9])\D*

您无需使用非捕获组(?:)将其包围。

答案 1 :(得分:2)

  

我想检查时间戳之前和之后是否存在非数字字符。非数字字符不需要存在,但不应该在之前或之后直接存在数字字符。我不想捕获这个非数字字符。

匹配此类时间戳的最佳方法是使用lookarounds

(?<!\d)(2[0-3]:[0-5][0-9]:[0-5][0-9]|[0-1][0-9]:[0-5][0-9]:[0-5][0-9])(?!\d)

如果时间戳前有数字,则(?<!\d)会失败,如果时间戳后面有数字,则(?!\d)会失败。

如果您使用

\D*(2[0-3]:[0-5][0-9]:[0-5][0-9]|[0-1][0-9]:[0-5][0-9]:[0-5][0-9])\D*

(请注意(?:...)非捕获组仅阻碍正则表达式引擎,内部模式仍然匹配,消耗字符),您将不会获得重叠匹配(如果时间戳之后有时间戳) 。但是,我认为这是一种罕见的情况,因此您仍然可以使用正则表达式并获取捕获组1中的值。

另外,请参阅How Negative Lookahead Works的答案。负面的lookbehind工作方式类似,但在匹配(消费)模式之前使用文本。

JS解决方案是使用捕获组

var re = /(?:^|\D)(2[0-3]:[0-5][0-9]:[0-5][0-9]|[0-1][0-9]:[0-5][0-9]:[0-5][0-9])(?=\D|$)/g;
var text = "Some23:56:43text here Some13:26:45text there and here is a date 10/30/89T11:19:00am";
while ((m=re.exec(text)) !== null) {
  document.body.innerHTML += m[1] + "<br/>";
}