Vim regular expression to remove all but last two digits of number
Solution 1
Group 3 is defined as being 2 digits long. If you want to match the last 4 digits you want \(\d\d\d\d\)
with no *
at the end. If you just want to match all digits but the first 4, put your *
inside the group match rather than outside.
Solution 2
As written, your regex captures one digit, then three digits, then any number of groups of two digits each. The third match will, therefore, always be two digits if it exists. In your particular test case, the '89' is in \4, not \3.
Changing the regex to
1,$s/\(\d\)\(\d\d\d\)\(\d\d\+\)\>/\3\g
will give you '6789' as the result, since it will capture two or more digits (up to as many as are there) in the third group.
Solution 3
You want to use a noncapturing group here, like so
1,$s/\(\d\)\(\d\d\d\)\(\%(\d\d\)*\)\>/\3/g
which gives 6789
as the result here, and if input was changed to
2345678
would change the line to 278
chappar
Updated on June 11, 2022Comments

chappar 4 months
I have following text in a file
23456789
When I tried to replace the above text using command
1,$s/\(\d\)\(\d\d\d\)\(\d\d\)*\>/\3\g
I am getting
89
. Shouldn't it be6789
? Can anyone tell me why it is89
.
Brian Carper over 13 yearsNote, if you us the \v switch you can avoid all of those backslashed parens. 1,$s/\v(\d)(\d\d\d)(\d\d)*>/\3/g is much easier to read.

AmirW about 11 yearsAre you looking for something like this: 1,$s/\v^\d{4}((\d{2})*)/\1/


chappar over 13 yearsshouldn't * at the group 3 match last 2,4,6.. digits?

chappar over 13 years(\d\d)* matches 2 or multiple of 2's. In our case it should match last 4 digits. So, shouldn't \3 contain all the 4 digits. \4 will have nothing as i have only 3 ().

chappar over 13 yearsWhy do i need a extra set of parenthesis at group 3? what was the problem with my original example?

orip over 13 years(\d\d)* would indeed match any digit pairs, but it won't capture them for you to use later. To capture it you need to wrap it in its own group  that's the extra set of parentheses.

rampion over 13 years(\d\d)* does match digits of length multiples of 2 (so 12, 3456, but not 789), but it only captures the last atom, since the same parentheses (the same capturing group) are used for multiple pairs of numbers. To make sure you're only matching even multiple lengths, use Hasturken's regex.

lambacck about 13 yearsI was actually looking for the noncapturing group for vim regex.