How do I group regex atoms in Vim without creating a backreference?
Answer
\%(pattern\)
Explanation
In Vim's regex engine, \( and \) create a capturing group whose contents are stored in \1, \2, etc. and can affect performance. \%( and \%) create a non-capturing group — it groups atoms for alternation or quantifiers without the overhead of storing the match.
How it works
\%(pattern\)— grouppatternfor operator precedence or alternation, without storing the submatch- Use this whenever you don't need a backreference in the replacement or a later part of the pattern
- Non-capturing groups are faster in searches with many repetitions because Vim doesn't track what matched inside them
Example
Match lines ending with foo or bar without a backreference:
/\%(foo\|bar\)$
Compare with a capturing version (identical match, but stores the result in \1):
/\(foo\|bar\)$
Using \%(\) for alternation inside a larger substitution:
:%s/\%(https\|http\):\/\//URL: /g
This matches both https:// and http:// and replaces them with URL: , without using a backreference that could conflict with \1 used elsewhere in the pattern.
Tips
- In
\v(very magic) mode,%(and)work as non-capturing groups without backslashes:/\v%(foo|bar)$ - Prefer
\%(\)over\(\)when building complex patterns with:substituteif you only need grouping for alternation or quantifiers - Numbered captures
\1–\9are only counted from capturing groups; inserting a non-capturing group does not shift the numbering