In the buffer
You have a build log and you want the dates written with periods instead of hyphens. The build names and statuses also contain hyphens, and those must stay. You have selected the date column with <C-v>2j9l. Before:
2026-10-12 build-01 passed
2026-10-13 build-02 failed
2026-10-14 build-03 re-run
^
After typing :'<,'>s/\%V-/./g and pressing Enter:
2026.10.12 build-01 passed
2026.10.13 build-02 failed
2026.10.14 build-03 re-run
^
Six hyphens change, all inside the selected columns. build-01 and re-run keep theirs. The cursor lands at the start of the last line that had a substitution.
When you would reach for it
You have selected a column in block mode, typed :, run a substitution, and watched it rewrite the whole line, because the '<,'> range only ever means “these lines.” Tables, aligned logs, fixed-width reports and columns of numbers all have this problem: the text you want to change also appears outside the column. \%V is the missing half. The range picks the lines, and \%V tells the pattern which columns count.
Gotchas
- Leave out
\%Vand the block is ignored.:'<,'>s/-/./gon the same selection changes all ten hyphens, includingbuild.01andre.run. The range has no notion of columns; only the pattern does. \%Vchecks one position, the place where it sits in the pattern. A multi-character match can start inside the block and run past its edge. With only2026-selected,\%V-1still matches-1and eats the1outside the block. To pin both ends, put a second\%Vbefore the last character:\%V-\%V1matches nothing there, which is correct.\%Vreads the last visual area, the onegvwould reselect, not the current range. That means it keeps working after you leave visual mode and even with:%s, but if you make another selection in between, the pattern follows the new one.- Extending the block with
$makes it ragged, reaching to the end of every line however long.\%Vhonors that, so<C-v>2j$from the build column changesre-runtoo.
Variants
:'<,'>s/\%V\d\+/0/g
Any pattern works after \%V. This zeroes out every number that starts inside the block and leaves numbers in other columns alone.
:'<,'>s/\%Vfoo\%Vo/bar/g
The guarded form for longer matches: \%V at the start and before the last character, so the whole fooo must sit inside the selection.
gv
Reselects the area that \%V is using. Run it first when you are unsure which columns the pattern will see.