正则表达式让前瞻对字符串中的每个单独的单词起作用

RegEx getting lookaheads to work for each separate word in a string

我正在尝试创建一个正则表达式以从包含多个单词的字符串中提取 单个 参考编号。

参考编号是任何包含 6 个或更多字符的大写 alpha-numeric 单词。即 GAF7887979、897979 等

到目前为止,我正在使用以下内容来捕获这些引用:[A-Z\d-]{6,} 结合正数 look-ahead 以确保匹配中至少有一个数字:(?=.*\d)

但是我需要过滤掉一个特定格式的日期,如下所示:19MAR19 为此,我使用了负数 look-ahead:(?!\d{2}[A-Z]{3}1\d) 这似乎有效很好。

最终的正则表达式是:(?!\d{2}[A-Z]{3}1\d)(?=.*\d)[A-Z\d-]{6,}

所以这一切都适用于单个单词,但在包含多个单词的字符串中,look-ahead 似乎不适用于每个单词,而是适用于整个字符串(可以理解),所以如果字符串中至少有一位数字,一切都会匹配:(

有没有办法让 look-ahead 到 re-apply 到正则表达式中的每个新词?

示例:

这里的要点是限制.在lookahead里面。请注意 . 匹配除换行符以外的任何字符。前瞻 (?=.*\d) returns true 如果在 any 0+ 个字符之后有一个数字而不是换行字符,因此, 所有 words before a valid match are also matched.

由于您只匹配大写字母和数字,因此请使用 [A-Z\d]* 而不是 .*

您还需要单词边界以确保整个单词都匹配。

使用

\b(?!\d{2}[A-Z]{3}1\d)(?=[A-Z\d]*\d\b)[A-Z\d-]{6,}\b

regex demo

详情

  • \b - 前导词边界
  • (?!\d{2}[A-Z]{3}1\d) - 没有 2 位数字,3 个大写 ASCII 字母,1 和单词边界后的数字
  • (?=[A-Z\d]*\d\b) - 必须有任何 0+ 大写字母 or/and 数字和后跟单词边界的数字
  • [A-Z\d-]{6,} - 六个或更多 digits/letters/-
  • \b - 后跟单词边界。