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

How do I use a VimScript expression as the replacement in a substitution?

Answer

:s/pattern/\=expression/g

Explanation

Prefixing the replacement string with \= in a :substitute command tells Vim to evaluate the rest as a VimScript expression rather than literal text. This turns :s into a programmable transformation engine — you can increment numbers, reformat matches, apply string functions, or compute entirely new values on the fly.

How it works

  • \= — switch the replacement side into expression mode
  • submatch(0) — the entire matched text
  • submatch(1) — the first capture group \(…\) in the pattern
  • Any VimScript function or expression is valid: toupper(), printf(), arithmetic, etc.

Example

Increment all numbers on the current line:

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

Before:

item 3, qty 5, total 8

After:

item 4, qty 6, total 9

Zero-pad all numbers to three digits across the file:

:%s/\d\+/\=printf('%03d', submatch(0))/g

Uppercase every word on selected lines:

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

Tips

  • Use \(…\) in the pattern and submatch(1), submatch(2) to reference individual capture groups in your expression
  • String concatenation with . works: \='prefix_' . submatch(0) . '_suffix'
  • Works with :global: :%g/^-/s/\d\+/\=submatch(0)*2/g doubles numbers only on lines starting with -
  • The expression is evaluated once per match, so counters via setreg or :let variables inside the expression increment correctly across a global replace

Next

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