Wednesday, September 2, 2009

vim negative match using negative look-ahead assertion


The second part to the mildly popular vim regex negative match post. This time we'll use the zero-width negative look-ahead assertion feature in vim.

I'll show 3 different ways this can be used.


  1. The first one is in my opinion, the most useful. Suppose you want to find all instances of foo which are NOT followed by bar. For example, we want to match foobear but not foobarstool. The vim search command for this is:

    /foo\(bar\)\@!


    So the first part is easy. We want to match foo, so that starts the regex. Next we want to indicate that we don't want bar following foo, so we put bar and the negative look-ahead assertion multi indicator
     \@! 

    The negative-look ahead assertion multi applies only to an atom though. So if we didn't put the parentheses around bar, the assertion would only apply to the letter r. So that's why we need the parentheses.

  2. The second way to do use it is simply apply the negative look-ahead assertion to an atom without a match in front of it like so:

    \(bar\)\@!

    Try it and you'll see that it is pretty useless as it will match most everything. (Exercise: how can you get this expression to not match a certain spot? :)

  3. The third way to use this can mimic the

    :v/somepattern/p


    command described in an earlier post. So do this:

    /^\(\(.*sommepattern.*\)\@!\).*


    This kind of mimics the global command. I'm not entirely certain if the behavior is the same on blank lines (ie. lines withonly the newline/CR character on it). This one is mostly academic though as I would use the global v command anyway. :)








No comments: