Come posso eseguire: sostituire solo una parte della linea e non tutta?


15

Ho una linea come questa:

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

Voglio sostituire i caratteri dello spazio (all'interno dei nomi dell'argomento) con trattino basso. Vorrei quindi utilizzare:

:s/\ /_/g

ma come posso scegliere di non applicarlo all'intera linea, ma partendo, per esempio, dalla posizione del cursore? (O la terza parola)?


4
In una regex, per descrivere la posizione corrente del cursore puoi usare l'atomo \%#. Quindi, è possibile utilizzare: :s/\v(%#.*)@<= /_/g. Che potrebbe essere descritto come uno spazio preceduto da @<=caratteri ( ) dopo la posizione del cursore.
user9433424

1
Sia tu che Statox avete proposto il \%#trucco, accetterò la sua risposta se non ne scrivete una ... Ma uno di voi potrebbe spiegare la regexp con un po 'più esplicitamente?
Feffe

Risposte:


15

È possibile utilizzare la seguente soluzione:

Primo utilizzo v$per selezionare il testo dal cursore alla fine della riga. Quindi utilizzare il seguente comando:

:s/\%V\ /_/g

Il \%Vindicano per modificare il testo nella zona precedentemente selezionata visivamente, vedere :h /\%V.

Se prendo il tuo esempio:

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

Se il mio cursore si trova sulla quarta colonna e utilizzo il comando che ho appena scritto ottengo:

function my_function(argument, another argument,_but_there_are_spaces)

In risposta al tuo commento puoi anche usare

  • \%# che corrisponde dalla posizione del cursore
  • \%>23c che corrisponde dopo la 23a colonna.
  • \%>'m che corrisponde dopo la posizione di un segno

Vedi :h /\%#, :h /\%>ce :h /\%>'m.

@ User9433424 ha dato un modo di usare \%#nel suo commento. Per il motivo con il segno puoi impostarlo con spirito mae quindi usare:

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

Una spiegazione del modello fornita da @ User9433424 è la seguente:

: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

Ti consigliamo di vedere :h \ve:h /\@<=


Funziona benissimo! Ma non sono abituato alle selezioni visive e l'intero processo sembra un po '"pesante" ... Pensi che potrebbe esserci qualcosa di più veloce?
Feffe

Sì, lasciami aggiornare la mia risposta :)
statox

User9433424 ti ha dato questo suggerimento poco prima di te, ma hai risposto quindi accetterò la tua risposta se va bene - potresti forse spiegare lo schema regexp che usa un po 'di più? Sto ancora lottando con questo ...
Feffe

Ho cercato di rendere la risposta il più chiara possibile, ma se @ User9433424 scrive la propria risposta, non esitate ad accettarla.
statox

1
Molto bella spiegazione della regexp, grazie! E grazie per il tuo commento sulla cui risposta accettare :)
Feffe

5

Puoi usare look behind ( :h \@<=) per assicurarti che ci sia un precedente '(', e un limite di fine parola ( :h \>) per assicurarti che la sostituzione avvenga dove vuoi.

Quindi, con il testo:

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

eseguendo il comando:

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

produrrà:

function my_function(argument, another_argument, but_there_are_spaces)

Questo potrebbe essere più facile che dover posizionare il cursore ogni volta, a condizione che la sostituzione abbia sempre un punto di partenza noto.


2
La sostituzione non ha sempre un punto di partenza noto: era solo per ... correggere una strana serie di refusi che ho fatto. Ma la tua risposta è comunque interessante, grazie!
Feffe
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.