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.