Comment puis-je exécuter: remplacer sur une partie seulement de la ligne et pas sur toute la ligne?


15

J'ai une ligne comme celle-ci:

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

Je veux remplacer les caractères d'espace (à l'intérieur des noms de l'argument) par un trait de soulignement. Je voudrais donc utiliser:

:s/\ /_/g

mais comment puis-je choisir de ne pas l'appliquer à toute la ligne, mais à partir, disons, de la position du curseur? (Ou le troisième mot)?


4
Dans une expression régulière, pour décrire la position actuelle du curseur, vous pouvez utiliser l'atome \%#. Ainsi, vous pouvez utiliser: :s/\v(%#.*)@<= /_/g. Ce qui pourrait être décrit comme un espace précédé de ( @<=) caractères après la position du curseur.
— user9433424

1
Vous et Statox avez tous deux proposé l' \%#astuce, j'accepterai sa réponse si vous n'en écrivez pas une ... Mais l'un ou l'autre d'entre vous pourrait-il expliquer le regexp avec un peu plus explicitement?
— Feffe

Réponses:


15

Vous pouvez utiliser la solution suivante:

Utilisez d'abord v$pour sélectionner le texte du curseur jusqu'à la fin de la ligne. Utilisez ensuite la commande suivante:

:s/\%V\ /_/g

Pour \%Vindiquer de modifier le texte dans la zone précédemment sélectionnée visuellement, voir :h /\%V.

Si je prends votre exemple:

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

Si mon curseur se trouve sur la 40e colonne et que j'utilise la commande que je viens d'écrire, j'obtiens:

function my_function(argument, another argument,_but_there_are_spaces)

En réponse à votre commentaire, vous pouvez également utiliser

  • \%# qui correspond à la position du curseur
  • \%>23c qui correspond après la 23e colonne.
  • \%>'m qui correspond après la position d'une marque

Voir :h /\%#, :h /\%>cet :h /\%>'m.

@ User9433424 a donné un moyen d'utiliser \%#dans son commentaire. Pour le motif avec la marque, vous pouvez le définir avec ma, puis utiliser:

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

Une explication du modèle donné par @ User9433424 est la suivante:

: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

Vous aurez envie de voir :h \vet:h /\@<=


Ça fonctionne bien ! Mais je ne suis pas vraiment habitué aux sélections visuelles et l'ensemble du processus semble un peu "lourd" ... Pensez-vous qu'il pourrait y avoir quelque chose de plus rapide?
— Feffe

Oui, permettez-moi de mettre à jour ma réponse :)
— statox

User9433424 a donné cet indice juste avant vous, mais vous avez répondu, donc je vais accepter votre réponse si cela vous convient - pourriez-vous peut-être expliquer le modèle d'expression rationnelle qu'il utilise un peu plus? Je suis toujours aux prises avec ça ...
— Feffe

J'ai essayé de rendre la réponse aussi claire que possible mais si @ User9433424 écrit sa propre réponse, n'hésitez pas à l'accepter.
— statox

1
Très belle explication de l'expression rationnelle, merci! Et merci pour votre commentaire sur la réponse à laquelle accepter :)
— Feffe

5

Vous pouvez utiliser look behind ( :h \@<=) pour vous assurer qu'il y a un «(» précédent et une limite de fin de mot ( :h \>) pour vous assurer que la substitution se produit où vous le souhaitez.

Donc, avec le texte:

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

exécution de la commande:

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

produira:

function my_function(argument, another_argument, but_there_are_spaces)

Cela pourrait être plus facile que de devoir positionner le curseur à chaque fois, à condition que la substitution ait toujours un point de départ connu.


2
La substitution n'a pas toujours un point de départ connu: c'était uniquement pour ... corriger une étrange série de faute de frappe que j'ai faite. Mais votre réponse est néanmoins intéressante, merci!
— Feffe
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.