8

For example, if I have $asd['word_123'] and I wanted to replace it with $this->line('word_123'), keeping the 'word_123'. How could I do that?

By using this:

%s/asd\[\'.*\'\]/this->line('.*')/g

I will not be able to keep the wording in between. Please enlighten me.

Conner
  • 27,462
  • 8
  • 47
  • 72
Eric T
  • 1,008
  • 3
  • 17
  • 39

2 Answers2

22

Using regex, you could do something like :%s/\$asd\['\([^']*\)'\]/$this->line('\1')/g

Step by step:

%s - substitute on the whole file

\$asd\[' - match "$asd['". Notice the $ and [ need to be escaped since these have special meaning in regex.

\([^']*\) - the \( \) can be used to select what's called an "atom" so that you can use it in the replacement. The [^'] means anything that is not a ', and * means match 0 or more of them.

'\] - finishes our match.

$this->line('\1') - replaces with what we want, and \1 replaces with our matched atom from before.

g - do this for multiple matches on each line.

Alternative (macro)

Instead of regex you could also use a macro. For example,

qq/\$asd<Enter>ct'$this->line(<Esc>f]r)q

then @q as many times as you need. You can also @@ after you've used @q once, or you can 80@q if you want to use it 80 times.

Alternative (:norm)

In some cases, using :norm may be the best option. For example, if you have a short block of code and you're matching a unique character or position. If you know that "$" only appears in "$asd" for a particular block of code you could visually select it and

:norm $T$ct'this->line(<C-v><Esc>f]r)<Enter>

For a discourse on using :norm more effectively, read :help :norm and this reddit post.

Conner
  • 27,462
  • 8
  • 47
  • 72
  • 1
    This worked great for me, thanks! But for some reason I always have to do ".,$" instead of "%s" for the whole file. Is that a quirk with my vim installation? – NickO May 01 '14 at 18:10
  • Potentially, however be advised that `:.,$` is not the same as `:%`. The former does from the _current_ line to the end while the later does every line. An alternative would be `:0,$`. – Conner May 01 '14 at 18:14
2

Try using

:%s/\$asd\[\'\([^\']\+\)\'\]/$this->line('\1')/g
Vaman Kulkarni
  • 3,151
  • 2
  • 18
  • 19