0

I am using Vim version 9.0.1280.

The search and replace command I am using is -

:%s/\(_\)\([1-9]\{1\}\)\(_\)/_0\1_/gc

When I run this vim offers to replace _1_ with _0\1_.

What am I doing wrong?

2
  • The string that's offered is before \1 is expanded to "1" so after accepting, it should be fine (except that your substitution produces "_0__" in the end)
    – Friedrich
    Feb 15 at 10:57
  • 1
    Isn't \1 referring to \(_\) part? And \2 to \([1-9]\{1\}\) part…
    – gildux
    Feb 16 at 20:04

2 Answers 2

0

I would do:

:%s/\(_\)\([1-9]\{1\}\)\(_\)/_0\2_/gc

Or more compact:

:%s/_\zs\d\{1\}\ze_/0&/gc

I limit the part of the regular expression I want to replace with \zs and \ze and I can use the full pattern \0 replacement expression.

Or as @gildux mention:

:%s/\v_(\d{1})_/_0\1_/gc
4
  • 1
    Thanks. This worked
    – gautam
    Feb 15 at 11:43
  • 1
    I type \0 as &, but either work
    – D. Ben Knoble
    Feb 16 at 15:18
  • Good idea, one character less ;-) Feb 16 at 15:32
  • 1
    It's possible to use \1 by avoiding useless grouping in search (at least it appears so to me without knowing further context.) So :%s/_\([1-9]\{1\}\)_/_0\1_/gc witch can be shorten under Vim to :%s/_\(\d\+\)_/_0\1_/gc
    – gildux
    Feb 16 at 20:12
1

When Vim says, replace with _0\1_ ..., it hasn't replaced the \1 you typed with the first group yet.

The first group in your expression is \(_\), so the resulting text after the substitution is _0__.

You want the matched number which is the second group. So to fix your original regexp, just use \2 instead of \1:

:%s/\(_\)\([1-9]\{1\}\)\(_\)/_0\2_/gc

However as gildux points out, there's no need to create groups for the underscores. You can just use a single group for the bit you actually want to re-use:

:%s/_\([1-9]\)_/_0\1_/gc
                          " The search pattern is:
    _                     " an underscore followed by:
     \(     \)            " group \1, containing
       [1-9]              " a non-zero digit
              _           " followed by another underscore

Note that I've also removed the \{1\} from your original query. [1-9] already matches one atom, so specifying you want to match one of them doesn't make much sense in this context! (Perhaps your example is slimmed down from your real use-case.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.