我有一个像这样的多行字符串:
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
请注意,\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/