15

I frequently find myself trying to do transformations like

  author    = {{foo
                bar}},

to

  author    = {foo
                bar},

and I can't find a regex to match the part in between the curly braces.

%s/{{\(.*\)}}/{\1}/g

doesn't work since . does not match newlines. But [\.\r] or something doesn't seem to work either. I tried [\s\S] as well to match whitespace and non-whitespace, but to no avail.

1
  • I know this is old, but I think with surround.vim you can do ds{
    – D. Ben Knoble
    Commented Mar 24, 2020 at 18:57

2 Answers 2

31

You should use \_.\{-} instead of .*.

\_. matches any character including end-of-line. However, as :h \_. warns, using it with * will match all text to the end of the buffer.

\{-} is similar to *, matching 0 or more instances of the proceeding atom. But it matches as few as possible instead of as many as possible. This makes \{-} safe if your example pattern appears more than once. For example:

author = {{foo
           bar}},

editor = {{buz
           baz}},

Using %s/{{\(\_.*\)}}/{\1}/g changes the starting double brace for author, but the closing double brace for editor. Since * matches as many atoms as possible, the pattern matches until the last double brace it finds. This results in the following:

author = {foo
           bar}},

editor = {{buz
           baz},

However, using %s/{{\(\_.\{-}\)}}/{\1}/g gives the desired result for both author and editor as it stops searching at the first double brace it finds:

author = {foo
           bar},

editor = {buz
           baz},
2
1

Turns out one must use \_.* instead of ..

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.