仅在未找到重复行时才匹配的正则表达式

Regex that only matches when no duplicate lines are found

我有一个像这样的多行字符串:

SA21 abcdef
BKxyz
SA21 abcdef

我需要一个仅在 ^SA21 abcdef$ 行出现一次时才匹配的正则表达式。所以它不应该匹配第一个例子,但它应该匹配这个:

BK udsia
SA21 abcdef
BKxyz

我试图捕获该行并确保它仅在以后找不到同一行时才匹配:/(^SA21 abcdef$)(?!)/m regex101 但这不起作用,因为它可能总是匹配最后一行...

如果该行在单次出现之前或之后不存在,则您想要的正则表达式应该只匹配 。这是通过一个温和的贪婪令牌实现的:

/\A(?:(?!^SA21 abcdef$).)*(^SA21 abcdef$)(?:(?!^SA21 abcdef$).)*\z/ms

regex demo

(?:(?!^SA21 abcdef$).)* 是与 SA21 abcdef 行开头以外的任何文本匹配的标记。 /s 修饰符是必需的,以便 . 可以匹配换行符。

但是,该构造非常耗费资源,展开它是个好主意:

/\A(?:\n+(?!SA21 abcdef$).*)*\n*^(SA21 abcdef)$(?:\n+(?!SA21 abcdef$).*)*\z/m

another demo

请注意,\A\z 是明确的 start/end string 锚点,/m 修饰符不会影响它们。

图案解释:

  • \A - 字符串开头
  • (?:\n+(?!SA21 abcdef$).*)* - 零个或多个序列:
    • \n+ - 1 个或多个换行符 ...
    • (?!SA21 abcdef$) - 后面不跟 SA21 abcdef 那是整行
    • .* - 除换行符外的零个或多个字符
  • \n* - 零个或多个换行符
  • ^ - 行首
  • (SA21 abcdef) - 必须是单行的行
  • $ - 行尾
  • (?:\n+(?!SA21 abcdef$).*)* - 见上文
  • \z - 字符串结尾。