vimtricks.wiki Concise Vim tricks, one at a time.

How do I use a Vim expression to dynamically compute the replacement in a substitution?

Answer

:s/\d\+/\=submatch(0)+1/g

Explanation

The \= prefix in a :substitute replacement field tells Vim to evaluate the following as a Vimscript expression rather than treating it as a literal string. This turns :s into a Turing-complete transformation engine — you can compute replacements based on match content, counters, or any Vim function.

How it works

  • \= — switches the replacement field to expression mode
  • submatch(0) — the full matched text (equivalent to & in normal replacement)
  • submatch(1), submatch(2), etc. — captured groups
  • Any Vimscript expression, function call, or operator is valid

Example

Increment every number on the current line by 1:

:s/\d\+/\=submatch(0)+1/g

Given:

version 2, patch 14, build 307

Result:

version 3, patch 15, build 308

Convert matched words to uppercase:

:s/\<\w\+\>/\=toupper(submatch(0))/g

Insert a line counter (using a variable that increments):

:let i=1 | g/^/s/^/\=i.'. '/ | let i+=1

This numbers every line in the file.

Tips

  • printf() is handy for zero-padded numbers: \=printf('%03d', submatch(0)+1)
  • Combine with \%V to limit to a visual selection
  • Works with :g//s/// for filtered replacements across the file

Next

How do I match a pattern only when it is preceded or followed by another pattern, without including that context in the match?