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

标签 regex multiline

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

SA21 abcdef
BKxyz
SA21 abcdef

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

BK udsia
SA21 abcdef
BKxyz

我 try catch 该行并确保仅当稍后找不到同一行时才匹配:/(^SA21 abcdef$)(?!\1)/m regex101但这不起作用,因为它可能总是与最后一行匹配......

最佳答案

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

/\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 是明确的开始/结束 字符串 anchor ,即 /m 修饰符不会影响他们。

模式解释:

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

关于仅在未找到重复行时才匹配的正则表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38524501/

相关文章:

regex - PHP运行多实例问题

regex - 需要正则表达式来匹配单词或字符串结尾

javascript - 在正则表达式字符括号中包含连字符?

正则表达式匹配在任意位置连字符并分成两行的特定单词

java - Android:强制textview包装内容

regex - grep 多行模式

asp.net - 多行文本框中的自动高度

regex - Haskell 正则表达式性能

javascript - 正则表达式 - 避免表达式中出现字符串

c# - c#中逐字字符串的多行格式(前缀为@)