2010-06-04 16 views
7

que tengo texto en el formato siguientes aparatos:expresiones regulares vim para la sustitución de los espacios entre comillas

ERR_OUT_OF_MEM, "ERR OUT OF MEM" 
ERR_SOMETHING_BAD, "ERR SOMETHING BAD" 

quiero reemplazar todos los espacios en el texto que están dentro de las frases con guiones:

ERR_OUT_OF_MEM, "ERR_OUT_OF_MEM" 
ERR_SOMETHING_BAD, "ERR_SOMETHING_BAD" 

La mejor expresiones regulares que podía llegar a es:

\("\w\+\)\@<= 

(hay un espacio al final de ese)

pero esto solo encuentra el primer espacio en cada cadena entrecomillada, y necesitaría repetir esto varias veces para obtener el efecto deseado.

¿Alguna manera de hacerlo de una vez?

Gracias!

Respuesta

6

Sin duda hay un patrón 0 de longitud que funciona en una sola pasada, pero como yo no tenía mucho éxito con ellos, yo prefiero este tipo de enfoque:

:%s/\%("[^"]*"\)*\("[^"]*"\)/\=substitute(submatch(1), ' ', '_', 'g')/g 

Nota: las comillas dobles se mantienen agrupados 2 por 2 con el fin de no transformar

foo bar "foo bar" "foo barr" 

en

foo bar "foo_bar"_"foo_barr" 

EDIT: como se señaló rampion o ut, el siguiente es más que suficiente:

%s/"[^"]*"/\=substitute(submatch(0), ' ', '_', 'g')/g 
+0

Por qué no utilizar el '/ "[^"] *" 'patrón/No entiendo lo omitir los pares iniciales de comillas te compra (con '\% (" [^ "] *" \) * ') – rampion

+0

Buen punto. Me convencieron de que la búsqueda comenzaría de nuevo no después de la cita de cierre, sino después de la de apertura. Corrijo la expresión regular. Gracias. –

6

Esto no es una solución de propósito general, ya que coincidirá con cualquier espacio que aparece en cualquier lugar después de una cita doble en una línea, pero debería funcionar para cuerdas en el formato que ha especificado:

s/\v(\".*)@<= /_/g 

he utilizado el (verymagic) símbolo \ v porque creo que hace que la expresión regular un poco más fácil de leer, y yo incluido todo el comando de sustitución, ya que la 'g' al final es importante.

Para los siguientes en casa, esta expresión regular primero establece el modo 'muy mágico' con \ v. Luego define el token (\".*) que significa "una comilla doble y luego cualquier otra cosa" y usa la aseveración lookbehind @<= para decir "solo unir cosas después de esa última ficha" - en otras palabras, solo haga coincidir las cosas que vienen después de una comilla doble . Finalmente, hay un espacio, que es el que realmente se empareja, y el término de sustitución es un guión bajo, que es con lo que queremos reemplazarlo, y el g dice "sustituir todos los términos coincidentes" para que no solo obtengamos el primero coincidencia encontrada.

+0

Esto funciona, pero también reemplaza los espacios que tengo al final de la línea. –

+0

Ah. Sí, si tiene espacios al final, necesitará un enfoque más complejo. Luc, arriba, debería hacerlo. –

0

Mi PatternsOnText plugin proporciona un comando :SubstituteInSearch. Con él, usted primera búsqueda de las cadenas entre comillas, a continuación, realizar una :substitute sólo dentro de los partidos:?

/".\{-}" 
:SubstituteInSearch/_/ /g 
Cuestiones relacionadas