You could also try the following substitution command:
%s/\v(^(.{-},){4}.*)@<=,/:/g
The pattern is:
\v(^(.{-},){4}.*)@<=,
Which can be broken down like this:
\v(^(.{-},){4}.*)@<=,
| ||| | | | | |
| ||| | | | | +--- a comma
| ||| | | | +--- the previous subpattern must be matched before what follows
| ||| | | +--- `.*` any text
| ||| | +--- repeat the previous subpattern `.{-},` 4 times
| ||| |
| ||| |
| ||| +--- `.{-},` a minimum of text before a comma
| ||+--- capture the `.{-},` subpattern to apply the multi `{4}` to it
| |+--- beginning of a line (anchor)
| +--- capture the `^(.{-},){4}.*` subpattern to apply the multi `@<=` to it
+--- very magic mode
The @<=
multi doesn't add anything to the pattern, it just asks the regex engine to make sure that at least 4 commas are found before the commas you want to substitute with a colon.
Also, there are 2 subpatterns you're capturing but you don't use any backreference to them (\1
, \2
, ..., \9
), so you could tell Vim that you don't want it to count them as sub-expressions by prefixing a %
sign before each open parenthesis:
%s/\v%(^%(.{-},){4}.*)@<=,/:/g
According to the help (:h /\%(
), it makes the pattern a little bit faster.
I'm not sure, but more generally, it should work for other patterns too.
Suppose you wanted to replace all the occurrences of foobar
, but ignoring the first N
ones on any given line. Then, you could adapt the previous substitution command like this:
%s/\v(^(.{-}foobar){N}.*)@<=foobar/replacement/g