devendra
devendra

Reputation: 175

vim: Selectively replacing brackets in a file

I have following text file:

A(B C)
D(E F)
A(G 
H 
I)

I want to convert this to:

modifiedA{B C}
D(E F)
modifiedA{G 
H
I}

Usually, I would use s/A(/modifiedA\{/g and s/)/}/g.

Since I don't want to touch the line with D(E F), this won't work.

Thank you for your comments/help.

Update:

  1. The answer should not require human intervention and should be scalable. Hence, using c instead of g is not an option.

  2. Also note that A() can be spread across multiple lines.

Upvotes: 0

Views: 64

Answers (4)

pro-gramer
pro-gramer

Reputation: 184

You can use this:
:%s/\(A\)(\(B C\))/modified\1{\2}/g | %s/\(A\)(\(G\)/modified\1{\2}/g | %s/\(I\))/\1}/g

Let's break it down:

  • :s: abbrevation for the :substitute command.
  • /: start of the pattern.
  • \(A\): captures 'A' in the first capture group.
  • (: a literal '('
  • \(B C\): captures 'B C' in the second capture group.
  • ): a literal ')'
  • /: end of the pattern. Start of the substitution.
  • \1: backreference to the first capture group ('A').
  • {\2}: backreference to the second capture group ('B C') surrounded by literal braces.
  • /g: end of substition and the flag 'g' makes the substitution apply multiple times per line.

The '|'s between the commands make them execute one after another automatically.

Note that this answer relies on 'A', 'D' and 'I' being literals. Otherwise they could include the following parenthesed text. If you are working with more complex text, I suggest you do multiple substitutions rather than single command.

See also: :help :|
:help pattern.txt
:help usr_27.txt

Upvotes: 0

SergioAraujo
SergioAraujo

Reputation: 11800

In order to match a multiline pattern we need \_.\{-} which means non-greedy regex search:

:%s/\(A\)(\(\_.\{-}\))/modified\1{\2}

\( ................ start of a regex group
\) ................ end of a regex group
\_.\{-} ........... non-greedy regex
\1 ................ back reference to the regex group 1

Using very magic option see :h \v.

%s/\v(A)\((\w \_.{-})\)/modified\1{\2}

Upvotes: 1

steffen
steffen

Reputation: 16938

This was an answer to the first version of the question.

The substitute command supports the flag c for confirmation:

[c] Confirm each substitution.  Vim highlights the matching string (with
|hl-IncSearch|).  You can type:             *:s_c*
    'y'     to substitute this match
    'l'     to substitute this match and then quit ("last")
    'n'     to skip this match
    <Esc>   to quit substituting
    'a'     to substitute this and all remaining matches {not in Vi}
    'q'     to quit substituting {not in Vi}
    CTRL-E  to scroll the screen up {not in Vi, not available when
        compiled without the |+insert_expand| feature}
    CTRL-Y  to scroll the screen down {not in Vi, not available when
        compiled without the |+insert_expand| feature}
If the 'edcompatible' option is on, Vim remembers the [c] flag and
toggles it each time you use it, but resets it when you give a new
search pattern.
{not in Vi: highlighting of the match, other responses than 'y' or 'n'}

See

:help :s_flags

Upvotes: 0

Kent
Kent

Reputation: 195039

You can do it by recording and replaying a vim macro: (for example, q):

Recording:

qq/A(<Enter>%%r{``r}q

Replaying:

99@q

This works as long as the (...) for A are well paired. It works even in nesting cases:

enter image description here

Upvotes: 1

Related Questions