How do I do a case-preserving search and replace in Vim?
Answer
:%s/\v(old)/\=toupper(submatch(0)[0]).tolower(submatch(0)[1:])/g
Explanation
Standard substitutions don't preserve the original case of matched text. Using \= expression replacement with submatch() and case functions, you can replace words while keeping their original capitalization pattern — uppercase stays uppercase, lowercase stays lowercase.
How it works
\=in the replacement enables expression evaluationsubmatch(0)returns the full matched texttoupper()/tolower()convert case- By checking the case of the original, you can mirror it in the replacement
Example
Replace "old" with "new" preserving case:
:%s/\v\c(old)/\=submatch(0)[0]=~#'[A-Z]' ? 'New' : 'new'/g
Before: Old and old and OLD
After: New and new and NEW (with additional logic for all-caps)
Tips
- The
abolish.vimplugin provides:S/old/new/g(Subvert) for easy case-preserving substitution - For simple two-case scenarios, run two substitutions:
:%s/Old/New/g | %s/old/new/g - Use
\Cto force case-sensitive matching::%s/\Cold/new/g submatch(0) =~# '[A-Z]'tests if the match starts with uppercase