Wie kann ich laufen: nur einen Teil der Leitung ersetzen und nicht alles?

15

Ich habe eine Zeile wie diese:

function my_function(argument, another argument, but there are spaces)

Ich möchte die Leerzeichen (innerhalb der Argumentnamen) durch Unterstriche ersetzen. Ich möchte also verwenden:

:s/\ /_/g

aber wie kann ich wählen, dass es nicht auf die gesamte Zeile angewendet wird, sondern beispielsweise ab der Cursorposition? (Oder das dritte Wort)?

Feffe
quelle
4
In einer Regex können Sie zur Beschreibung der aktuellen Cursorposition das Atom verwenden \%#. So könnten Sie verwenden: :s/\v(%#.*)@<= /_/g. Dies könnte als ein Leerzeichen beschrieben werden, dem ( @<=) Zeichen nach der Cursorposition vorangestellt sind .
user9433424
1
Sie und Statox haben beide den \%#Trick vorgeschlagen , ich werde seine Antwort akzeptieren, wenn Sie keinen schreiben ... Aber könnte einer von Ihnen den regulären Ausdruck etwas expliziter erklären?
Feffe

Antworten:

15

Sie könnten die folgende Lösung verwenden:

Verwenden Sie zuerst v$den Text vom Cursor bis zum Ende der Zeile an. Dann benutze den folgenden Befehl:

:s/\%V\ /_/g

Die \%Vweisen darauf hin, den Text im zuvor visuell ausgewählten Bereich zu ändern, siehe :h /\%V.

Wenn ich dein Beispiel nehme:

function my_function(argument, another argument, but there are spaces)

Wenn sich mein Cursor in der 40. Spalte befindet und ich den Befehl verwende, den ich gerade geschrieben habe, erhalte ich:

function my_function(argument, another argument,_but_there_are_spaces)

Als Antwort auf Ihren Kommentar können Sie auch verwenden

  • \%# die von der Cursorposition übereinstimmt
  • \%>23c welches nach der 23. Spalte übereinstimmt.
  • \%>'m die nach der Position einer Marke übereinstimmt

Siehe :h /\%#, :h /\%>cund :h /\%>'m.

@ User9433424 gab eine Möglichkeit, \%#in seinem Kommentar zu verwenden. Für das Muster mit der Markierung können Sie es mit setzen maund dann verwenden:

:s/\%>'a /_/g

Eine Erklärung des von @ User9433424 angegebenen Musters lautet wie folgt:

:s/\v(%#.*)@<= /_/
:s/                    substitution command
   \v                  Enable the very magic mode
      %#.*             Any characters from the cursor position
           @<=         Check for matches just before what follows
              space    Followed by a space
               /_/     Substitute the matches by underscores

Du wirst sehen wollen :h \vund:h /\@<=

statox
quelle
Es funktioniert gut ! Aber ich bin nicht wirklich an visuelle Auswahlen gewöhnt und der gesamte Prozess scheint ein wenig "schwer" zu sein ... Glaubst du, es könnte etwas schnelleres geben?
Feffe
Ja, lassen Sie mich meine Antwort aktualisieren :)
statox
User9433424 hat diesen Hinweis kurz vor Ihnen gegeben, aber Sie haben geantwortet. Ich werde Ihre Antwort akzeptieren, wenn dies in Ordnung ist. Können Sie vielleicht das Regexp-Muster erklären, das er ein wenig mehr verwendet? Ich habe immer noch
Probleme
Ich habe versucht, die Antwort so klar wie möglich zu gestalten, aber wenn @ User9433424 seine eigene Antwort schreibt, zögere nicht, sie zu akzeptieren.
statox
1
Sehr schöne Erklärung des regulären Ausdrucks, danke! Und
vielen
5

Sie können look behind ( :h \@<=) verwenden, um sicherzustellen, dass ein vorangestelltes '(' und eine Wortende-Grenze ( :h \>) vorhanden sind, um sicherzustellen, dass die Ersetzung dort erfolgt, wo Sie sie möchten.

Also mit dem Text:

function my_function(argument, another argument, but there are spaces)

Befehl ausführen:

:s/\((.*\)\@<=\> /_/g

wird herstellen:

function my_function(argument, another_argument, but_there_are_spaces)

Dies ist möglicherweise einfacher, als den Cursor jedes Mal neu positionieren zu müssen, vorausgesetzt, die Substitution hat immer einen bekannten Startpunkt.

Antonius
quelle
2
Die Substitution hat nicht immer einen bekannten Ausgangspunkt: Sie sollte nur ... eine seltsame Serie von Tippfehlern korrigieren, die ich gemacht habe. Aber Ihre Antwort ist trotzdem interessant, danke!
Feffe