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

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 mode
  • submatch(0) — the entire matched string
  • submatch(N) — the Nth capture group (like \1 but 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 let variable 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-expression for the complete reference
  • Works in :global commands too: :g/pattern/s/old/\=expr/g

Next

How do I open a specific buffer in a new split without navigating away from my current buffer?