0

I have lines like the following ones (actually function prototypes)

void ()
word ( word, another word, one_more word, ..., hello, ... )
one argument ( only )

I want to match each single argument and enclose it between < and >.

Before wasting time with the replacement string, I'm trying to devise the proper search pattern. The following command

:%s/\(( \|, \)\(.\{-}\)\( )\|,\)/\1<\2>\3/g

only matches and replace odd-position arguments.

Enlico
  • 2,194
  • 15
  • 31

1 Answers1

3

It's because your matching groups have overlap! Exept for zero-width pattern items, every charachter in your string will be consumed in the matching. so here you can use \zs and \ze to confine your match:

:%s/\%(( \|, \)\zs\(.\{-}\)\ze\%( )\|,\)/<\1>/g

Here i also changed the first and third captuting groups to non-capturing as we don't need to capture them. for a complete list of zero-width pattern items, see: :h pattern-overview

dNitro
  • 401
  • 4
  • 5
  • Oh, this answer is what I was looking for! BTW, while waiting for it I tried another simpler search pattern %s/ \(\w[^,)]\+\)/<\1>/g. This is good too, but it fails when something (not necessarly a comment) follows the closing parenthesis. What do you think about it? – Enlico Sep 18 '16 at 22:12
  • @EnricoMariaDeAngelis So first capture anything between parethesis and do substitution on them; with your pattern: %s/(\zs\(.*\)\ze)/\=substitute(submatch(1), '\(\w[^,)]\+\)', '<\1>', 'g') – dNitro Sep 18 '16 at 23:52
  • Thank you for the answer. However I found another related question here. – Enlico Sep 19 '16 at 09:15