Vim Tips Wiki
Advertisement

Positive lookahead with \@=

Negative lookahead with \@!

If you want to search for a pattern only when it occurs next to another pattern, use the regex features “lookahead” and “lookbehind” (collectively “lookaround”). If you want to search for a pattern only when it doesn't occur next to another, use their complements, “negative lookahead” and “negative lookbehind” (“negative lookaround”).

Match start and end[]

The simplest and most performant way to do positive lookaround in most cases is to mark the start and/or end of your match with \zs and \ze. The parts of the pattern before the \zs and/or after the \ze match with zero length. In other words, they must be found in the text in order to make a match, but will not be included in the match. That means they won't be substituted or highlighted.

Examples[]

  • foo \zsbar\ze baz matches the “bar” in foo bar baz. But the whole pattern is still required, so it doesn't match at all for foo bar qux or foo bar or foo.

You can use one or the other alone:

  • mi \zscasa matches “casa” if preceded by “mi ”. So it matches only the first “casa” in mi casa es su casa.
  • dad\ze. matches “dad” if followed by a period. So it matches only the second “dad” in My dad is bigger than your dad.

Help[]

Classic lookaround[]

If you're familiar with PCRE or other regex engines, you may prefer lookahead and lookbehind assertions. Negative lookaround is also the only way to assert that a certain pattern is not present.

The following strings with @ are assertions that the preceding atom (which may be a group) does or does not exist just ahead or behind the current position in the pattern. The atom (or its absence) will match with zero length.

lookbehind lookahead
positive (atom)\@<= (atom)\@=
negative (atom)\@<! (atom)\@!

In very magic mode:

lookbehind lookahead
positive (atom)@<= (atom)@=
negative (atom)@<! (atom)@!

Examples[]

  • \(foo \)\@<=bar\( baz\)\@= matches the “bar” in foo bar baz. But the lookaround groups are still required, so it doesn't match at all for foo bar qux or foo bar or foo.
    • (foo )@<=bar( baz)@= in very magic mode.
  • \(mi \)\@<=casa matches “casa” if preceded by “mi ”. So it matches only the first “casa” in mi casa es su casa.
  • \(mi \)\@<!casa matches “casa” if not preceded by “mi ”. So it matches only the second “casa” in mi casa es su casa.
  • dad.\@= matches “dad” if followed by a period. So it matches only the second “dad” in My dad is bigger than your dad.
  • dad.\@! matches “dad” if not followed by a period. So it matches only the first “dad” in My dad is bigger than your dad.

Help[]

External links[]

See also[]

Advertisement