【问题标题】:Exclude a specific pattern from Regex match从正则表达式匹配中排除特定模式
【发布时间】:2015-05-06 05:47:40
【问题描述】:

有点延续我的previous 问题:

我遇到了另一种我必须注意的模式,它看起来像这样:

Tue 01/24/12 1/24/2012 2:56:25 PM

在这种情况下,我只希望它与 1/24/2012 2:56:25 PM 部分匹配。

我之前的表达式似乎与01/24/12 1 或类似内容上的上述输入相匹配。

大部分情况下,我可以通过使用以下表达式来完成这项工作:

(?:\w\w\w (0?[1-9]|1[012])[- \/.](0?[1-9]|[12][0-9]|3[01])[- \/.](19|20)?\d\d)? (0?[1-9]|1[012])[- \/.](0?[1-9]|[12][0-9]|3[01])[- \/.](19|20)?\d\d((?: |\s*-\s*)(?:(?:([01]?\d|2[0-3]):)?([0-5]?\d):)?([0-5]?\d)( AM| PM)?)?

这里的问题是我不想在我的匹配中实际包含Tue 01/24/12 位;我想确保那部分不匹配。我试图通过将?! 修饰符添加到第一个非捕获组来使用否定的前瞻性,但它并没有完全按照我的想法做。

我试过查看类似的问题herehere,但答案没有解释任何内容;他们只是为该特定实例提供了一个工作表达式。

【问题讨论】:

  • 请看regex101.com/r/tR0yT3/1,我想您也想在输入字符串中捕获01/24/12
  • 我试图只捕获从第二个日期开始的日期(示例中为1/24/2012),因为在捕获它之后,我会将其转换为 .NET 日期时间对象。跨度>
  • 是的,但它是一个单独的匹配项。请再看一下regex101.com/r/tR0yT3/2 和匹配项。你在使用 C# 吗?请发布您的代码。
  • 您的正则表达式将在 01/24/12 1/24/2012 2:56:25 PM 中找到 2 个匹配项。否则,请重新制定要求。

标签: regex


【解决方案1】:

当您在正则表达式中使用 (...) 时,您正在创建将这些匹配项返回到组中的捕获组。

在你的情况下,你只需要创建一个包含你想要的输出的组,记住我改变了你的正则表达式,并且组 $4 有你想要的输出:

(?:\w\w\w (0?[1-9]|1[012])[- \/.](0?[1-9]|[12][0-9]|3[01])[- \/.](19|20)?\d\d)? ((0?[1-9]|1[012])[- \/.](0?[1-9]|[12][0-9]|3[01])[- \/.](19|20)?\d\d((?: |\s*-\s*)(?:(?:([01]?\d|2[0-3]):)?([0-5]?\d):)?([0-5]?\d)( AM| PM)?))?

在 regexr.com 上测试:

要解决您的间距匹配问题,您需要在第一个(...)之后包含空格吗?在第二个(...)内分组?组(我包括为 \s?),给你留下:

(?:\w\w\w (0?[1-9]|1[012])[- \/.](0?[1-9]|[12][0-9]|3[01])[- \/.](19|20)?\d\d)?(\s?(0?[1-9]|1[012])[- \/.](0?[1-9]|[12][0-9]|3[01])[- \/.](19|20)?\d\d((?: |\s*-\s*)(?:(?:([01]?\d|2[0-3]):)?([0-5]?\d):)?([0-5]?\d)( AM| PM)?))

最后一组也不能是(...)?否则你会匹配无穷大。

如果您不需要捕获它们,您还应该考虑将所有 (...) 组更改为 (?:...),将所需的输出留在 $1 中

【讨论】:

  • 我想知道这是否是最好的方法,但我不太确定是否有更简单的方法来排除特定模式。这一个几乎可以工作,但由于某种原因,它似乎也匹配文本中的每个空格字符。
  • 匹配空格字符是什么意思?可以举个例子吗?
  • 我知道问题出在哪里,但正在想办法解决。问题是第一个(...)之后的空间?团体。第二组也是(...)?在找到第一个模式后给你留下一个空间匹配