正则表达式丢弃整个捕获,如果它紧接在特定字符之前

Regex to discard an entire capture if it's immediately preceded by a specific character

给定以下文本:

somerandomtext06251/750/somerandomtext/21399/10 79/20 8301

如何提取 06251/750、79/20、8301 并忽略 21399/10?

一般规则:

我从以下匹配模式开始:

 (?<invnr>\d{2,}/?\d{2,})

总的来说,它可以工作,但只有一个问题:它也需要 21399/10。所以,我添加了一个负面的回顾:

 (?<!/)(?<invnr>\d{2,}/?\d{2,})

现在它忽略了 21399/10 的第一个数字(因为它前面有 /),但仍然捕获了后面的所有字符,即 1399/10。但我需要完全跳过 21399/10。

如何进行后视以放弃整个匹配项并跳到下一个匹配项,而不是只跳过一个数字?

您可以在否定回顾中添加数字模式(通过使用字符 class、[/\d] 将其与 / 组合)以确保匹配不会发生,如果它紧跟一个数字:

(?<![/\d])\d{2,}(?:/\d{2,})?

regex demo

详情

  • (?<![/\d]) - 如果在当前位置
  • 的左侧有 / 或数字,则匹配失败的否定后视
  • \d{2,} - 两位或更多位
  • (?:/\d{2,})? - / 和两个或更多数字的可选序列。

如果您需要确保只匹配 ASCII 数字,请将 RegexOptions.ECMAScript option 传递给 .NET 方法内的正则表达式编译器,或者使用 [0-9] 而不是 \d

请注意,您的 \d{2,}/?\d{2,} 有点偏差,因为它不会匹配 2 位或 3 位数字序列,只能匹配 4 位以上的数字序列。

尽管不如 稳健,您可以选择在模式之前提供允许字符的白名单:

(?<=^|[ a-z])[0-9]{2,}(?:\/[0-9]{2,})?

Regex demo

另一种方法是匹配以 / 开头的模式,并使用交替 |.[=19 捕获那些不在组 () 中的模式=]

/[0-9]{2,}(?:/[0-9]{2,})?|(?<invnr>[0-9]+(?:/[0-9]{2,})?)
  • /[0-9]{2,}(?:/[0-9]{2,})? 匹配带有前导的模式 /
  • |
  • (?<invnr>[0-9]+(?:/[0-9]{2,})?) 捕获组 invnr 中的模式

.NET Regex demo(单击 Table 选项卡查看组值)