Vim regular expression to remove all but last two digits of number

10,251

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 non-capturing 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

Share:
10,251
chappar
Author by

chappar

Updated on June 11, 2022

Comments

  • chappar
    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 be 6789? Can anyone tell me why it is 89.

    • Brian Carper
      Brian Carper over 13 years
      Note, 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
      AmirW about 11 years
      Are you looking for something like this: 1,$s/\v^\d{4}((\d{2})*)/\1/
  • chappar
    chappar over 13 years
    shouldn't * at the group 3 match last 2,4,6.. digits?
  • chappar
    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
    chappar over 13 years
    Why do i need a extra set of parenthesis at group 3? what was the problem with my original example?
  • orip
    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
    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
    lambacck about 13 years
    I was actually looking for the non-capturing group for vim regex.