¿Cómo puedo ejecutar: sustituir solo una parte de la línea y no toda?

15

Tengo una línea como esta:

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

Quiero sustituir los caracteres de espacio (dentro de los nombres de los argumentos) con guiones bajos. Por lo tanto, me gustaría usar:

:s/\ /_/g

pero, ¿cómo puedo elegir no aplicarlo a toda la línea, sino a partir de, por ejemplo, la posición del cursor? (O la tercera palabra)?

Feffe
fuente
44
En una expresión regular, para describir la posición actual del cursor, puede usar el átomo \%#. Por lo tanto, se puede utilizar: :s/\v(%#.*)@<= /_/g. Que podría describirse como un espacio precedido por ( @<=) caracteres después de la posición del cursor.
user9433424
1
Tanto tú como Statox propusieron el \%#truco, aceptaré su respuesta si no escribes una ... ¿Pero alguno de ustedes podría explicar la expresión regular con un poco más explícitamente?
Feffe

Respuestas:

15

Puede usar la siguiente solución:

Primero use v$para seleccionar el texto desde el cursor hasta el final de la línea. Luego use el siguiente comando:

:s/\%V\ /_/g

La \%Vindicación para cambiar el texto en el área previamente seleccionada visualmente, ver :h /\%V.

Si tomo tu ejemplo:

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

Si mi cursor está en la columna 40 y utilizo el comando que acabo de escribir, obtengo:

function my_function(argument, another argument,_but_there_are_spaces)

En respuesta a tu comentario también puedes usar

  • \%# que coincide desde la posición del cursor
  • \%>23c que coincide después de la columna 23.
  • \%>'m que coincide después de la posición de una marca

Ver :h /\%#, :h /\%>cy :h /\%>'m.

@ User9433424 dio una manera de usar \%#en su comentario. Para el patrón con la marca, puede configurarlo con ingenio may luego usar:

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

Una explicación del patrón dado por @ User9433424 es la siguiente:

: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

Querrás ver :h \vy:h /\@<=

statox
fuente
Funciona bien ! Pero realmente no estoy acostumbrado a las selecciones visuales y todo el proceso parece un poco "pesado" ... ¿Crees que podría haber algo más rápido?
Feffe
Sí, permítanme actualizar mi respuesta :)
statox
El usuario 9433424 dio esta pista justo antes que tú, pero respondiste, así que aceptaré tu respuesta si está bien, ¿podrías explicar el patrón de expresión regular que usa un poco más? Todavía estoy luchando con esto ...
Feffe
Traté de hacer la respuesta lo más clara posible, pero si @ User9433424 escribe su propia respuesta, no dude en aceptarla.
statox
1
Muy buena explicación de la expresión regular, ¡gracias! Y gracias por tu comentario sobre cuya respuesta aceptar :)
Feffe
5

Puede usar mirar detrás ( :h \@<=) para asegurarse de que haya un '(' anterior y un límite de fin de palabra ( :h \>) para asegurarse de que la sustitución se realice donde lo desee.

Entonces, con el texto:

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

ejecutando el comando:

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

Producirá:

function my_function(argument, another_argument, but_there_are_spaces)

Esto podría ser más fácil que tener que colocar el cursor cada vez, siempre que la sustitución siempre tenga un punto de partida conocido.

Antonio
fuente
2
La sustitución no siempre tiene un punto de partida conocido: fue solo para ... corregir una extraña serie de errores tipográficos que hice. Pero tu respuesta es interesante, ¡gracias!
Feffe