Is there a way to do negative lookahead in vim regex?

点点圈 提交于 2020-03-17 04:45:50

问题


In Vim, is there a way to search for lines that match say abc but do not also contain xyz later on the line? So the following lines would match:

The abc is the best
The first three letters are abc

and the following would not match:

The abc is the best but xyz is cheaper
The first three letters are abc and the last are xyz

I know about syntax like the following:

/abc\(xyz\)\@!

but that only avoids matching abcxyz and not if there is anything in between, such as abc-xyz. Using

/abc.*\(xyz\)\@!

also does not work because there are many positions later in the line where xyz is not matched.

(I should note that on the command line I would do something like grep abc <infile | grep -v xyz but I would like to do the above interactively in Vim.)


回答1:


Your attempt was pretty close; you need to pull the .* that allows an arbitrary distance between the match and the asserted later non-match into the negative look-ahead:

/abc\(.*xyz\)\@!

I guess this works because the non-match is attempted for all possible matches of .*, and only when all branches have been exhausted is the \@! declared as fulfilled.




回答2:


I always find it weird, that you need to escape brackets in vim, so I try to use the "very magic" mode most of the time, activated with \v:

/\vabc(.*xyz)@!



回答3:


Although your question is about lookahead, I found it while searching for lookbehind. Thus, I post the solution to lookbehind so that others may find it.

If you search for pattern2 not preceded by pattern1, that is negative lookbehind, search for:

\(pattern1\)\@<!pattern2



回答4:


This works for me /abc\(.*xyz\)\@!




回答5:


I think I'd write this as /abc\(\(xyz\)\@!.\)*$

I'm not sure whether this is faster than other suggestions (I think it might be since it tests each position only once) but it makes conceptual sense as:

"abc followed by anything which is not xyz, any number of times until end of line"

I like that better than "abc followed by anything not followed by xyz" as in the other patterns mentioned.



来源:https://stackoverflow.com/questions/21148467/is-there-a-way-to-do-negative-lookahead-in-vim-regex

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!