Today I want to use some regular expression for searching and replacing in my files. But I found that NVim’s regular expression engine has its own flavor, which is different from the regex engine used by Sublime Text.1 I ended up learning some of the basics of Nvim-style regex. In this post, I want to emphasize on how to use lookaround2 in Nvim.

Lookaround in Nvim

First, in Nvim, the syntax for look around is:

  • \@=: positive lookahead
  • \@!: negative lookahead
  • \@<=: positive lookbehind
  • \@<!: negative lookbehind

But how to use look around in Nvim? Let is take an example to explain this. Suppose we have text as follows:

foobar foo barfoo

To match foo which is followed by bar (bar not part of the match), use the following regex:

/foo\(bar\)\@=

In Nvim, ( and ) matches literally, which is different from PCRE. In order to use lookaround in Nvim, we have to include the lookaround pattern in a group, hence the escaped parentheses \(\) around bar.

So the first foo in the above text matches:

foobar foo barfoo
^
one match here

Similarly, we have the following 4 patterns:

  1. Match foo which is not followed by bar: /foo\(bar\)\@!
# now we have two matches
foobar foo barfoo
       ^      ^
       two matches here
  1. Match foo which is preceded by bar: /\(bar\)\@<=foo
foobar foo barfoo
              ^
              one match here
  1. Match foo which is not preceded by bar: /\(bar\)\@<!foo
foobar foo barfoo
^      ^
two matches here
  1. Match foo which is neither followed nor preceded by bar: /\(bar\)\@<!foo\(bar\)\@!
foobar foo barfoo
       ^
       one match here

\ze and \zs for positive lookaround

We may also use \zs and ze for positive lookbehind and lookahead. \zs means that the actual match starts from here and \ze means that the actual match ends here. Take the above foobar text as an example:

  • Match foo preceded by bar: \bar\zsfoo
  • Match foo followed by bar: foo\zebar

In the above two match, bar is not part of the match. You can see that\ze and \zs simplify the pattern for positive lookaround.

A last example

Let’s take another example (adapted from this post):

rs11223-A        -A
rs23300-G        -TTA
rs9733-T          -G
rs11900000-GT    -TTG

Suppose we want to find - in the first part of each line, how do we write the regex pattern?

Using positive lookbehind

With positive lookbehind, the pattern can be (definitely not the only one):

/\(\d\+\)\@<=-

In the above regex pattern, \+ means to match previous pattern 1 or more time, which is a bit different from what we are accustomed to in Sublime Text.

Using \zs

With \zs, we can simplify the match pattern:

/\d\+\zs-

Ok, that is all. Hope you can finally understand how to correctly use lookaround regex in Nvim.

References


  1. Use :h perl-patterns to find the difference of Nvim regex and perl’s regex.
  2. If you are not familiar with what lookaround in regex means, you can find a intro here and here