Case preserving substitute in Vim

VimReplace

Vim Problem Overview


Can this can be done in Vim?

> What I mean is: searching for 'BadJob' > and replacing with 'GoodJob' would do > the following replacements > > 'badjob' -> 'goodjob'
> 'BadJob' -> 'GoodJob'
> 'badJob' -> 'goodJob'
> 'BADJOB' -> 'GOODJOB'

Vim Solutions


Solution 1 - Vim

Use abolish.vim:

:%S/badjob/goodjob/g

Solution 2 - Vim

I don't know if this is the kind of solution you're looking for... but i've used this: keepcase.vim

There's no support otherwise in vim...

Solution 3 - Vim

sure u can

:s/\cbad/\= strpart(submatch(0), 0 ,1) == toupper(strpart(submatch(0), 0, 1)) ? "GOOD" : "good"/

ps. i'm guessing keepcase.vim encapsulates some similar logic :)

Solution 4 - Vim

For most (non-complex) cases, i recommend @rampion’s answer over mine.
If you got a minute, my post might be still be worthwhile, though. Level up your awareness for scripting gotchas.



You can just paste and adapt this:
(Of course, if you do this from time to time, you will want a plugin instead of this monstrosity. But for some who are in a hurry and only need it once, this is a quick hack for your pasting pleasure:)

:%s/\cbad\zejob/= ( submatch(0)[0] is# toupper(submatch(0)[0]) ? 'G' : 'g' ) . ( submatch(0)[1] is# toupper(submatch(0)[1]) ? 'OOD' : 'ood' )

Apart from the search pattern, you have to edit the four 'strings' in the replacement code: Edit the parts in bold: > :%s/\cbad\zejob/=
( submatch(0)[0] is# toupper(submatch(0)[0]) ? 'G' : 'g' ) .
( submatch(0)[1] is# toupper(submatch(0)[1]) ? 'OOD' : 'ood' )

Don't use this 'orange' version for pasting, since its linebreak characters will also break the command.

/\ze is vim regex syntactic sugar for marking a positive lookahead: The pattern after \ze is checked for, but not substituted.


is#?? Let me explain… (If interested.)

# (also in ==# and others) enforces case sensitivity. Otherwise, with :set ignorecase (which I use, because that is required for the useful :set smartcase), vim will consider 'a' == 'A'!!
http://i.stack.imgur.com/99eI5.jpg" height="140"> http://i.stack.imgur.com/UE9qp.jpg" height="140"> http://i.stack.imgur.com/Zeij0.jpg" height="140">
Crazy as it is, we really should account for it: Because it is user-settings-dependent, == should NEVAR be used! (Except where that would actually be what you want.) I will even follow the recommendation to use ==# when comparing integers: http://learnvimscriptthehardway.stevelosh.com/chapters/22.html#code-defensively

is# instead of ==# is another way of coding defensively: It improves type safety: http://google.github.io/styleguide/vimscriptguide.xml?showone=Type_checking#Type_checking
It should be used when comparing against a string literal.

'single-quoted' instead of "double quoted" strings are another good practice: http://google.github.io/styleguide/vimscriptguide.xml?showone=Strings#Strings


HT @fc. - this answer builds on their answer, fixing a few shortcomings.

Solution 5 - Vim

If you're only matching an exact (case-independent) string with a few possible capitalizations, another possibility is:

:s/abc/\={'abc':'xyz','Abc':'Xyz'}[submatch(0)]/i

Solution 6 - Vim

An alternative to the keepcase plugin is SmartCase - replacing words while keeping original case. (Don't let yourself be discourage by the bad ratings.)

Solution 7 - Vim

What about

:%s/\Cbadjob/goodjob/
:%s/\CBadJob/GoodJob/
:%s/\CbadJob/goodJob/  
:%s/\CBADJOB/GOODJOB/

See: https://stackoverflow.com/a/2287449/5599687

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiondavetapleyView Question on Stackoverflow
Solution 1 - VimMark LodatoView Answer on Stackoverflow
Solution 2 - VimLB40View Answer on Stackoverflow
Solution 3 - Vimfc.View Answer on Stackoverflow
Solution 4 - VimAaron ThomaView Answer on Stackoverflow
Solution 5 - VimrampionView Answer on Stackoverflow
Solution 6 - VimIngo KarkatView Answer on Stackoverflow
Solution 7 - VimGabrieleView Answer on Stackoverflow