Often times I find myself needing to modify the selection in a substitute command in a non-trivial way. From a recent example, I needed to convert the numbers in the id of the divs to hexadecimal after decrementing them by 1.

Basically, I had to convert

<div id="someprefix1">
	 ...
</div>
<div id="someprefix2">
	...
</div>
<div id="someprefix3">
	...
</div>
<div id="someprefix4">
	...
</div>
...
<div id="someprefix80">
	...
</div>

to

<div id="someprefix0">
	 ...
</div>
<div id="someprefix1">
	...
</div>
<div id="someprefix2">
	...
</div>
<div id="someprefix3">
	...
</div>
...
<div id="someprefix4F">
	...
</div>

Doing this manually is tiring, I could have used macros but I instead chose an even simpler approach.

Vim allows to use expressions in the replacement part of the substitute command if it starts with \=. So, the replacement can be simply done using \= and printf. What I did was simply use the following command after selecting the text in a visual selection.

:'<,'>s/\v(someprefix)(\d+)/\=printf("%s%X", submatch(1), submatch(2) - 1)

The breakdown is as follows:

References