Tengo un archivo con un montón de valores predeterminados de usuario. Quiero cambiar parte del texto, pero estoy luchando para encontrar un comparador y un sustituto. Usando el siguiente ejemplo:
###############################################################################
# Trackpad, mouse, keyboard, Bluetooth accessories, and input #
###############################################################################
# Trackpad: enable tap to click for this user and for the login screen
defaults write com.apple.driver.AppleBluetoothMultitouch.trackpad Clicking -bool true
Me gustaría reemplazar # Trackpad: ...
conrunning "Trackpad: ..."
Desglosando el problema, se me ocurrió algo usando un probador de expresiones regulares:
/\n\n#\s(.*)/g
Si intento usar esto en Vim, no funciona para mí:
:/\n\n#\s(.*)/running "\1"/g
Supongo que mi problema se reduce a dos preguntas específicas:
- ¿Cómo puedo evitar buscar
\n
caracteres y, en cambio, asegurarme de#
que no aparezca al final del grupo de búsqueda? - ¿Cómo puedo usar efectivamente los grupos de captura?
Hay algunas respuestas geniales a continuación. Es difícil elegir entre los tres, sin embargo, creo que la respuesta elegida es la más precisa para mi especificación original. Le recomiendo que pruebe las tres respuestas con el archivo real para ver cómo se siente al respecto.
fuente
:%s/\v\n\n#\s+(.*)/^M^Mrunning "\1"/
(agregó la bandera "mágica"). Es realmente difícil elegir una respuesta correcta para mi pregunta original, pero creo que esta respuesta es la más cercana a mi respuesta original esperada. También es el único que funciona en todo el archivo sin necesidad de seleccionar un rango.\r
lugar de^M
obtener nuevas líneas?Yo usaría algo como:
^#
para que coincida con el#
carácter anclado al comienzo de la línea (esto responde a la pregunta 1)\s\+
para que coincida con cualquier espacio en blanco una o más veces\(
para comenzar un grupo (esto responde a la pregunta 2).\{-}\
para emparejar cualquier personaje 0 o más veces de una manera no codiciosa ; esto es diferente.*
en el sentido de que trata de igualar lo menos posible y no tanto como sea posible. Intenta agregar un:
personaje en el comentario para ver por qué esto importa\)
para finalizar el subgrupo.:
coincide con un literal:
Luego reemplazamos esto con el texto que desea, y lo usamos
\1
para referirnos al grupo que capturamos.La sintaxis de expresión regular es un poco como la sintaxis wiki: hay un montón de ellas, todas se parecen a simple vista, ninguna de ellas es obviamente mejor que ninguna otra, pero hay muchas diferencias.
Hoy, las llamadas expresiones regulares "compatibles con Perl" son las predeterminadas de facto en la mayoría de los idiomas, ¡pero las expresiones regulares de Vim no son compatibles con las expresiones compatibles con Perl! La sintaxis de Vim regexp se remonta al menos a los años 70, cuando Perl ni siquiera estaba presente.
Puede ver esto con los subgrupos, donde debe usar
\(
y no(
(esto es compatible con la sintaxis 'básica' POSIX, pero no con la sintaxis 'extendida' POSIX más común o la sintaxis Perl). Puede controlar esto agregando la\v
bandera en un patrón (ver:help /\v
para más detalles), esto lo hará "más compatible", pero no completamente (todavía tiene que usar.{-}
para coincidencias no codiciosas, por ejemplo)Entonces, esto podría explicar por qué el uso de "un probador de expresiones regulares" casi, pero no del todo, funciona.
http://www.vimregex.com/ como una buena descripción / cheatsheet de Vim regexps.
fuente
:
. Vea el archivo completo para más detalles github.com/squarefrog/dotfiles/blob/master/osx/…Usted puede:
#
::/[^#]$/
#\s(.*)
al comienzo de la línea:s/\v^#\s(.*)/running "\1"/
Para usar grupos, necesita:
\(.*\)
o\v
:s/\v...
Combinándolo:
fuente