I want to do a search and replace in a latex file as follows:
:%s/\\todo{.*}/\1/gc
That should transform texts like "abc \todo{def} ghi" into "abc def ghi". It happens that when the \todo{...} command is inside another one, vim tries to match the second (closing) bracket with that of the outer command. For instance, "abc \textbf{def \todo{ghi} jkl}" becomes "abc \textbf{def ghi} jkl" when it should be "abc \textbf{def ghi jkl}".
Is there a way to match the corresponding bracket?
Edit:
Sorry for not pointing that out before. It would be nice if it could match exactly the correspondent bracket since there can be commands inside as well as ouside the \todo{...} command.
Edit:
"abc \todo{def \textbf{ghi} jkl}" -> "abc def \textbf{ghi} jkl"
"abc \textbf{def \todo{ghi} jkl}" -> "abc \textbf{def ghi jkl}"
Non Recursive
Tell it to match anything but {}s:
:%s/\\todo{\([^{}]\+\)}/\1/
Recursive
The Vim regex language doesn't support the conditional regexes that would be required to match patterns in the way you suggest.
But, you can use an external language like perl to do so:
:perldo $_ =~ s/\\todo ({( (?: [^{}]*+ | (?1) )* )}) /\2/gx
For more information about recursive regex's checkout this SO post. I also found We's Puzzling Blog helpful in sussing these kinds of regexes out.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With