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 replacementsubmatch(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('.'), orline2byte('.')inside the expression to incorporate position-aware logic - Multi-line transforms: apply the substitution over a range and use
submatch(0)withsplit()/join() - Combine with
:g/pattern/to limit which lines are affected before running the expression substitution