Fallerhaltender Ersatz in Vim

154

Kann das in Vim gemacht werden?

Was ich meine ist: Wenn Sie nach 'BadJob' suchen und durch 'GoodJob' ersetzen, werden die folgenden Ersetzungen vorgenommen

'badjob' -> 'goodjob'  
'BadJob' -> 'GoodJob'  
'badJob' -> 'goodJob'  
'BADJOB' -> 'GOODJOB'
Davetapley
quelle
16
Dies sollte eine vim-Funktion sein. Es macht so viel Sinn.
Bach

Antworten:

120

Verwenden Sie abolish.vim :

:%S/badjob/goodjob/g
Mark Lodato
quelle
13
Wir haben Tim Pope nicht verdient.
Andrew Keeton
1
Dieses Plugin scheint bei mir nicht zu funktionieren. Wenn ich ein Wort mag BadJobund es durch ersetzen möchte GoodJob, kann ich es nicht verwenden %S/badjob/goodjob/g. Es kann keine Übereinstimmung festgestellt werden.
Roymunson
@Roymunson Was Sie tun müssen, ist %S/BadJob/GoodJob/gFolgendes : Dann wechselt der Befehl Subvertieren in den Mixed-Case-Modus und führt alle von OP angegebenen Substitutionen aus.
Shivams
28

Ich weiß nicht, ob dies die Art von Lösung ist, nach der Sie suchen ... aber ich habe diese verwendet: keepcase.vim

Es gibt sonst keine Unterstützung in vim ...

LB40
quelle
11

Sicher kannst du

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

ps. Ich vermute, keepcase.vim kapselt eine ähnliche Logik :)

fc.
quelle
Ja, seit 2007 ::% SubstituteCase / \ cbadjob / GoodJob / g ^^
Luc Hermitte
Bedeutung seit gVim 7.2? Ich habe es in gVim 7.1 (12. Mai 2007) versucht und es funktioniert nicht :(
fc.
Nein, ich habe dem Plugin 2007 den Befehl: SubstituteCase hinzugefügt. Das ist alles. Das Plugin ist auf vim.org verfügbar und wird bei den meisten Plugins nicht wie gewohnt mit vim ausgeliefert.
Luc Hermitte
1. Dies schlägt fehl, wenn der Benutzer hat :set ignorecase. 2. Badwird durch GOODanstelle von ersetzt Good. 3. Der " job" Teil der Frage wird ignoriert, daher wird auch lambada→ ersetzt lamgooda. Korrekturen und Erklärungen für diese Fehler und einige andere Dinge in meiner Antwort . (Auch LOLOWLs!)
Aaron Thoma
7

Sie können dies einfach einfügen und anpassen:
(Wenn Sie dies von Zeit zu Zeit tun, möchten Sie natürlich ein Plugin anstelle dieser Monstrosität. Aber für einige, die es eilig haben und es nur einmal brauchen, ist dies ein schneller Hack für dein klebevergnügen :)

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

Abgesehen vom Suchmuster müssen Sie die vier 'Zeichenfolgen 'im Ersatzcode bearbeiten : Bearbeiten Sie die Teile in Fettdruck :

:% s / \ c bad \ ze job / \ =
(Submatch (0) [0] ist # toupper (Submatch (0) [0])? ' G ': ' g ').
(Submatch (0) [1] ist # toupper (Submatch (0) [1])? ' OOD ': ' ood ')

Verwenden Sie diese 'orangefarbene' Version nicht zum Einfügen, da die Zeilenumbruchzeichen den Befehl ebenfalls unterbrechen.

/\zeist vim regex syntaktischer Zucker zum Markieren eines positiven Lookaheads: Das Muster danach \zewird überprüft, aber nicht ersetzt.


is#?? Lassen Sie mich erklären ... (Bei Interesse.)

#(auch in ==#und andere ) erzwingt die Groß- und Kleinschreibung. Ansonsten wird vim mit :set ignorecase(was ich benutze, weil das für das Nützliche erforderlich ist :set smartcase) berücksichtigen 'a' == 'A'!!

So verrückt es auch ist, wir sollten es wirklich berücksichtigen: Da es von den Benutzereinstellungen abhängt, ==sollte NEVAR verwendet werden! (Außer wo das eigentlich das ist, was Sie wollen.) Ich werde sogar der Empfehlung folgen, die ==#beim Vergleich von ganzen Zahlen verwendet werden soll: http://learnvimscriptthehardway.stevelosh.com/chapters/22.html#code-defensively

is#Stattdessen ==#gibt es eine andere Möglichkeit, defensiv zu codieren: Es verbessert die Typensicherheit: http://google.github.io/styleguide/vimscriptguide.xml?showone=Type_checking#Type_checking
Es sollte beim Vergleich mit einem Zeichenfolgenliteral verwendet werden.

'single-quoted'Anstelle von "double quoted" Zeichenfolgen gibt es eine weitere bewährte Methode: http://google.github.io/styleguide/vimscriptguide.xml?showone=Strings#Strings


HT @fc. - Diese Antwort baut auf ihrer Antwort auf und behebt einige Mängel.

Aaron Thoma
quelle
4

Wenn Sie nur eine exakte (von Groß- und Kleinschreibung unabhängige) Zeichenfolge mit einigen möglichen Groß- und Kleinschreibung abgleichen, besteht eine andere Möglichkeit:

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

Eine Alternative zum Keepcase- Plugin ist SmartCase, bei dem Wörter ersetzt werden, während der ursprüngliche Fall beibehalten wird . (Lassen Sie sich nicht von den schlechten Bewertungen entmutigen.)

Ingo Karkat
quelle
1
Gibt es einen Trick, um die schwer zu merkenden und mühsamen Befehle wie zu verkürzen :%s/file\A\?size/\=SmartCase("LastModifiedTime")/ig?
Michael Härtl
@ MichaelHärtl: Du kannst den :SmartCaseBefehl benutzen . Ich habe das in meiner eigenen Gabel verlängert . Beachten Sie, dass hierfür eine Ingo-Bibliothek als Abhängigkeit erforderlich ist.
Ingo Karkat