我有一个像这样的多行字符串:
SA21 abcdef
BKxyz
SA21 abcdef
我需要一个仅在
^SA21 abcdef$
行出现一次时才匹配的正则表达式。所以它不应该与第一个例子匹配,但它应该与这个匹配:BK udsia
SA21 abcdef
BKxyz
我试图捕获该行并确保它仅在以后找不到同一行时才匹配:
/(^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/