Dominic Dos Santos
Dominic Dos Santos

Reputation: 2713

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

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.

Upvotes: 60

Views: 26272

Answers (5)

Yao Li
Yao Li

Reputation: 3

I don't have enough reputation to comment Andy's answer, but his answer is wrong, so I explain it here, the expression"/abc\ [^d][^e][^f][^g]" is not match 'abc d111', 'abc def1' etc. the best way is the expression "/abc (defg)@!"

Upvotes: 0

Lee H
Lee H

Reputation: 5177

Here we go, this is a hairy one:

/\%(\%(.\{-}\)\@<=XXXXXX\zs\)*

(replace XXXXXX with the search word). This will search for everything that does not contain XXXXXX. I imagine if you did:

/abc \%(\%(.\{-}\)\@<=defg\zs\)*

This may work like you want it to. Hope this helps a little!

Upvotes: 1

rampion
rampion

Reputation: 89123

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.

Upvotes: 24

bmdhacks
bmdhacks

Reputation: 16441

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 \@!

Upvotes: 74

Andy
Andy

Reputation: 39

/abc\ [^d][^e][^f][^g]

It's pretty cumbersome for larger words, but works like a charm.

Upvotes: -3

Related Questions