Today I want to use some regular expressions for searching and replacing in my files. But I found that Nvim/Vim regular expression engine has its own flavor, which is different from the regex engine used by Sublime Text1. I ended up learning some of the basics of Nvim-style regex. In this post, I want to share about 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:
- Match
foo
which is not followed bybar
:/foo\(bar\)\@!
# now we have two matches
foobar foo barfoo
^ ^
two matches here
- Match
foo
which is preceded bybar
:/\(bar\)\@<=foo
foobar foo barfoo
^
one match here
- Match
foo
which is not preceded bybar
:/\(bar\)\@<!foo
foobar foo barfoo
^ ^
two matches here
- Match
foo
which is neither followed nor preceded bybar
:/\(bar\)\@<!foo\(bar\)\@!
foobar foo barfoo
^
one match here
Combine magic mode and look around#
Several months after I first wrote this article, I learned that Nvim also has a
very magic
mode (see :h /magic
for more info) which behaves more like
PCRE. The
very magic
mode is activate by preceding the search pattern with \v
. In the
very magic
mode, you have to remove the \
character from the look around
pattern. So in the very magic mode, the following regex should be used instead:
- positive look ahead:
@=
- negative look ahead:
@!
- positive look behind:
@<=
- negative look behind:
@<!
For example, to match foo
which is followed by bar
, you should use:
\vfoo(bar)@=
\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 bybar
:\bar\zsfoo
- Match
foo
followed bybar
: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.