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

How do I use an expression in a substitution to perform arithmetic on matched numbers?

Answer

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

Explanation

Vim's substitute command supports using a VimScript expression as the replacement by prefixing it with \=. Combined with submatch(), this lets you capture matched text and apply arithmetic or any Vim function to it — useful for incrementing version numbers, adjusting port numbers, or batch-modifying any numeric values in a file.

How it works

  • \(\d\+\) — captures one or more consecutive digits as capture group 1
  • % — applies to the whole file (omit for current line only)
  • /g — replaces all occurrences per line
  • \= — signals that the replacement is a VimScript expression, evaluated for each match
  • submatch(1) — retrieves the text matched by group 1; Vim coerces it to a number automatically
  • The expression result submatch(1)+1 becomes the replacement text

Example

Given:

version 2, port 8080, timeout 30

Running :%s/\(\d\+\)/\=submatch(1)+1/g produces:

version 3, port 8081, timeout 31

Each number in the file is independently incremented by 1.

Tips

  • submatch(0) refers to the entire match; numbered groups start at 1
  • Combine with printf() for zero-padding: :\=printf('%04d', submatch(1)+1)
  • To double all numbers: :%s/\(\d\+\)/\=submatch(1)*2/g
  • With very magic mode: :%s/\v(\d+)/\=submatch(1)+1/g (cleaner syntax)
  • The expression can call any Vim function: toupper(), len(), substitute(), etc.

Next

How do I enable matchit so % jumps between if/else/end style pairs?