Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vim: How do I search for a word which is not followed by another word?

Tags:

regex

vim

Pretty basic question, I'm trying to write a regex in Vim to match any phrase starting with "abc " directly followed by anything other than "defg".

I've used "[^defg]" to match any single character other than d, e, f or g.

My first instinct was to try /abc [^\(defg\)] or /abc [^\<defg\>] but neither one of those works.

like image 491
Dominic Dos Santos Avatar asked Sep 18 '08 20:09

Dominic Dos Santos


People also ask

How to cycle through search in vim?

Press Esc to cancel or press Enter to perform the search. Then press n to search forwards for the next occurrence, or N to search backwards. Type ggn to jump to the first match, or GN to jump to the last.

How to search backwards in vim?

In Vim, I know that / will search forward from the cursor, with n and N repeating the search forward and backward, respectively. I also know that ? will search backward from the cursor, with n and N repeating the search backward and forward, respectively.

How do I match a pattern in Vim?

In normal mode, press / to start a search, then type the pattern ( \<i\> ), then press Enter. If you have an example of the word you want to find on screen, you do not need to enter a search pattern. Simply move the cursor anywhere within the word, then press * to search for the next occurrence of that whole word.


2 Answers

Here's the search string.

/abc \(defg\)\@! 

The concept you're looking for is called a negative look-ahead assertion. Try this in vim for more info:

:help \@! 
like image 157
bmdhacks Avatar answered Sep 21 '22 22:09

bmdhacks


preceeded or followed by?

If it's anything starting with 'abc ' that's not (immediately) followed by 'defg', you want bmdhacks' solution.

If it's anything starting with 'abc ' that's not (immediately) preceeded by 'defg', you want a negative lookbehind:

/\%(defg\)\@<!abc / 

This will match any occurance of 'abc ' as long as it's not part of 'defgabc '. See :help \@<! for more details.

If you want to match 'abc ' as long as it's not part of 'defg.*abc ', then just add a .*:

/\%(defg.*\)\@<!abc / 

Matching 'abc ' only on lines where 'defg' doesn't occur is similar:

/\%(defg.*\)\@<!abc \%(.*defg\)\@!/ 

Although, if you're just doing this for a substitution, you can make this easier by combining :v// and :s//

:%v/defg/s/abc /<whatever>/g 

This will substitute '<whatever>' for 'abc ' on all lines that don't contain 'defg'. See :help :v for more.

like image 22
rampion Avatar answered Sep 21 '22 22:09

rampion