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 matchsubmatch(1)— retrieves the text matched by group 1; Vim coerces it to a number automatically- The expression result
submatch(1)+1becomes 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.