# vim match the outest bracket

How can I match the outest bracket and replace it with  in vim?

For example:

{a+b>c} --> $a+b>c$

{a+{\int_a^bf(x)dx=\set{a+c}}} --> $a+{\int_a^bf(x)dx=\set{a+c}}$

{a+{b+c}+d} and {e+{f}+g} --> $a+{b+c}+d$ and $a+{f}+g$


### UPDATE

By @Ingo Karkat's fascinating answer, I can search and replace correctly on each file. I would like to make this more easy to operate by:

1. All my file are with filetype tex;
2. I would like to define a shortcut key to make the search and replace though out the file with ft=tex

How can I do that? (I know this is maybe off topic, and I should solve it by reading vim's doc, but it will take me a lot of time since I am just a begginer user of vim...)

• Please don't drastically change the subject of your question after you've got several good answers. Mappings are straightforward in Vim; if you need any help please open a new question, and mark this question resolved by accepting the answer that helped you the best. – Ingo Karkat Dec 12 '16 at 7:44

Here's a macro approach that uses the % command to jump to matching curly braces. In contrast to my regular expression solution, this one handles multiple constructs in a line:

Preparation: Don't let search wrap around, the recursive macro would not end and eat into inner braces, too:

:set nowrapscan


Search for and go to the first opening brace:

gg/{


Clear register q and start recording:

qqqqq


Go to matching closing brace, back to front, replace, back to end, replace, go to next match:

%r$r$n


Recursively invoke macro, end macro recording, invoke macro:

@qq@q

• Note that you can simplify your macro with: %r$<C-O>. to replace one, or %%r$<C-O>.n to replace and search next like you do. – nobe4 Dec 8 '16 at 16:46

As long as there's only one such construct on each line, a simple greedy match (.*) will do. Capture the inner parts (including any {...} inside, up to the last available) in a named capture, and replace with $, captured text, $:

:%s/{$$.*$$}/$\1$/


Now, if there can be multiple constructs on a single line (e.g. {a+b>c} and {a+{\int_a^bf(x)dx=\set{a+c}}}), and you want to replace each (i.e. $a+b>c$ and $a+{\int_a^bf(x)dx=\set{a+c}}$, not $a+b>c} and {a+{\int_a^bf(x)dx=\set{a+c}}$, that's a whole different dimension. You would need to match opening and closing curly braces, something which cannot be done with Vim's regular expressions at all.

• I know that php has Recursive patterns, It seems that there is not correspondence in vim(perl)? – van abel Dec 8 '16 at 14:59
• No, unfortunately not. A completely different approach would be a macro using the % command; that one can indeed jump to matching braces. – Ingo Karkat Dec 8 '16 at 15:05

Also, if you like plugins, you can use vim-surround:

{a+b>c}
^
cursor here, type: cs{$(Change Surrounding { by$ )
v
{a+{\int_a^bf(x)dx=\set{a+c}}}


You have to move yourself to the outer context but once you're there, it's straightforward.

• Correct, that basically simplifies the %r$r$ part in my macro solution. – Ingo Karkat Dec 8 '16 at 16:14