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

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

Answer

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

Explanation

Prefixing the replacement string with \= in :substitute tells Vim to evaluate the rest as a Vimscript expression instead of a literal string. The expression is evaluated for every match, and its return value becomes the replacement text. This turns :s from a static find-and-replace into a full computational transform.

How it works

  • \= immediately after the second / activates expression mode for the replacement
  • submatch(0) returns the entire matched text (equivalent to & in a normal replacement)
  • submatch(1), submatch(2), etc. return capture group contents
  • Any Vimscript expression is valid: arithmetic, string functions, conditionals, function calls
  • The expression must return a string or a value that can be coerced to one

Example

Double every integer on the current line:

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

Before:

width=40, height=25, depth=8

After:

width=80, height=50, depth=16

Zero-pad all numbers in the visual selection to 4 digits:

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

Convert a comma-separated list to title case:

:%s/\v(\a)(\a*)/\=toupper(submatch(1)) . tolower(submatch(2))/g

Tips

  • Use line('.'), col('.'), or line2byte('.') inside the expression to incorporate position-aware logic
  • Multi-line transforms: apply the substitution over a range and use submatch(0) with split() / join()
  • Combine with :g/pattern/ to limit which lines are affected before running the expression substitution

Next

How do I replace every character in a visual block selection with the same character?