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?
Vi and Vim Stack Exchange is a question and answer site for people using the vi and Vim families of text editors. It only takes a minute to sign up.
Sign up to join this communityI 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
\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
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.)
\1
is expanded to "1" so after accepting, it should be fine (except that your substitution produces "_0__" in the end)\1
referring to\(_\)
part? And\2
to\([1-9]\{1\}\)
part…