tags:

views:

183

answers:

5

How to replace the strings (4000 to 4200 ) to (5000 to 5200) in vim ..

+5  A: 
:%s/\<4\([01][0-9][0-9]\)\>/5\1/g
Adrian Panasiuk
will work for all except 4200
monkey_p
Is there a setting so one can enter:s/<4(\[01][0-9][0-9])>/\5\1/g
jskulski
+1  A: 
:%s/\<4\([0-1][0-9][0-9]\)\>/5\1/g

will do 4000 to 4199. You would have to then do 4200/5200 separately.

A quick explanation. The above finds 4, followed by 0 or 1, followed by 0-9 twice. The 0-1,0-9,0-9 are wrapped in a group, and the replacement (following the slash) says replace with 5 followed by the last matched group (\1, i.e. the bit following the 4).

\< and > are word boundaries, to prevent matching against 14002 (thx Adrian)

% means across all lines. /g means every match on the line (not just the first one).

Brian Agnew
How will it work against the number 140002 ?
Adrian Panasiuk
You are missing a `\1`, unless I'm mistaken.
Tomalak
Good point. Corrected
Brian Agnew
@Tomalak - thanks. Typo on my behalf
Brian Agnew
+8  A: 

Another possibility:

:%s/\v<4([01]\d{2}|200)>/5\1/g

This one does 200 as well, and it does not suffer from the "leaning toothpick syndrome" too much since it uses the \v switch.

EDIT #1: Added word boundary anchors ('<' and '>') to prevent replacing "14100" etc.


EDIT #2: There are cases where a "word boundary" is not enough to correctly capture the wanted pattern. If you want white space to be the delimiting factor, the expression gets somewhat more complex.

:%s/\v(^|\s)@<=4([01]\d{2}|200)(\s|$)@=/5\1/g

where "(^|\s)@<=" is the look-behind assertion for "start-of-line" or "\s" and "(\s|$)@=" is the look-ahead for "end-of-line" or "\s".

Tomalak
I think that's the cleanest way since it handles the tricky 4200 case implicitly
Brian Agnew
this one will work for 4200 aswell
monkey_p
+1  A: 

If you didn't want to do a full search and replace for some reason, remember that ctrl-a will increment the next number below or after the cursor. So in command mode, you could hit 1000 ctrl-a to increase the next number by 1000.

If you're on Windows, see an answer in this question about how to make ctrl-a increment instead of select all.

Mark Rushakoff
A: 

More typing, but less thinking:

:%s/\d\+/\=submatch(0) >= 4000 && submatch(0) <= 4200 ? submatch(0) + 1000 : submatch(0)/g
Brian Carper