1

I had following code:-

      Time::Time(short y,short m,short d,short h,short mi,short s):
              (*this).y(y),
              (*this).m(m),
              (*this).d(d),
              (*this).h(h),
              (*this).mi(mi),
              (*this).s(s),   {};

I want to replace all (*this). with this->. when I select the above code and use command :%s/\%V(*this)./this->/g as give here, I get following code:-

 Time::Time(short y,short m,short d,short h,short mi,short s):
          (*this->y(y),
          (*this->m(m),
          (*this->d(d),
          (*this->h(h),
          (*this->mi(mi),
          (*this->s(s),   {};

here is the needed result:-

 Time::Time(short y,short m,short d,short h,short mi,short s):
          this->y(y),
          this->m(m),
          this->d(d),
          this->h(h),
          this->mi(mi),
          this->s(s),     {};

I know that I can remove (* manually but what if in future ,something like this but big text need to be replaced ?. that is why I am asking.

4

How to fix your regular expression

You need to "escape" the * character:

:%s/\%V(\*this)./this->/g

What's going wrong

The * character in an regular expression means: zero or more of the preceding atom, matching as many as possible. (See :help /star)

You intend (*this in your expression to match the literal (*this in your text. Instead, it will match this or (this or ((this or (((this etc.

Only the first of these (this not preceded by any brackets) exists in your text, so that is what the expression matches.

2

Alternative without Regex

Not answering the question (about Regex), just hope this may help anyone.

OP mentioned

when I select the above code in neovim and use command ...

If the block is selected, maybe a Block-Change command suits the situation more -- we have to type this-> anyways. (With Block selection: cthis-><Esc> or sthis-><Esc>, but s is documented here instead... :h visual-operators)

Read more here: :h blockwise-operators. Block Insert I and Append A are also quite useful sometimes.

By the way, if my cursor is at the ( and I have to block-select all (*this)., probably I would by (wrong) instinct do <C-v>www (oh I have gone too far -- I just w for extend selection) and then h (to go back) and then jjj...

A better way to select them maybe vab (so you don't have to be at the start of the selection when you enter Visual mode) and then <C-v> (change to block selection mode) and do the rest ljjj...

Hope this helps someone -- I feel more comfortable if I don't have to use commands, especially pressing : in Visual mode needs <C-u> to clear the '<,'> -- and Regex are hard to type.


P.S. I am primarily a Perl dev and I worked with Regex everyday and when I use Regex in (n)vim mostly I'll use very magic so I'll have to escape even the ().s... There are just too many Regex modes in Vim -- at least I've to be alert about all those characters. (Note the \v for very magic)

:%s/\%V\v\(\*this\)\./this->/g

In case you want a plain "replace", the very nomagic mode will have less margin for errors: (Because only the escaped ones have special meanings)

:%s/\%V\V(*this)./this->/g

Read more about the 4 Regex modes: :h magic

I only use the above 2 -- depending which has less to escape (Like \V for a lot of () in the string and \v for Perl-like regex functionality).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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