How do I use a Vim expression as the replacement string in a :s substitution?
Answer
:s/pattern/\=expr/g
Explanation
Vim's :s command normally replaces matches with a literal string. By starting the replacement with \=, you switch into expression mode — the replacement becomes the result of evaluating an arbitrary VimL expression. This unlocks computed replacements: math on captured groups, string transformations, function calls, and more.
How it works
\=at the start of the replacement string signals expression modesubmatch(0)— the entire matched stringsubmatch(N)— the Nth capture group (like\1but available as a VimL string)- The expression result is converted to a string and used as the replacement
Common patterns:
" Double every integer on the line
:s/\d\+/\=submatch(0)*2/g
" Uppercase the first letter of each match
:s/\w\+/\=toupper(submatch(0)[0]).submatch(0)[1:]/g
" Replace match with its length
:s/\w\+/\=len(submatch(0))/g
Example
Given a line:
width: 40, height: 80, depth: 120
Running :%s/\d\+/\=submatch(0)/2/g would leave numbers unchanged — but \=submatch(0)*2 doubles them:
width: 80, height: 160, depth: 240
Tips
- Use a
letvariable for stateful replacements (e.g., incrementing a counter across matches)::let i=1 | %s/ITEM/\='Item '.i.' ' | let i+=1/ge - Combine with
\v(very magic) for cleaner capture group syntax - Check
:help sub-replace-expressionfor the complete reference - Works in
:globalcommands too::g/pattern/s/old/\=expr/g