Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replace while keeping certain "words" in vi/vim

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.

like image 911
Eric T Avatar asked Jul 24 '12 04:07

Eric T


People also ask

How to replace exact word in vi editor?

Press y to replace the match or l to replace the match and quit. Press n to skip the match and q or Esc to quit substitution. The a option substitutes the match and all remaining occurrences of the match. To scroll the screen down, use CTRL+Y , and to scroll up, use CTRL+E .

How to replace a word with Vim?

Open the file in Vim. Press slash (/) key along with the search term like “/ search_term” and press Enter. It will highlight the selected word. Then hit the keystroke cgn to replace the highlighted word and enter the replace_term.

How do I find special characters in Vim?

To find a character string, type / followed by the string you want to search for, and then press Return. vi positions the cursor at the next occurrence of the string. For example, to find the string “meta,” type /meta followed by Return.


1 Answers

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.

like image 153
Conner Avatar answered Oct 07 '22 21:10

Conner