¿Cómo puedo hacer que mi pareja no sea codiciosa en vim?

481

Tengo un gran archivo HTML que tiene muchas marcas que se ve así:

<p class="MsoNormal" style="margin: 0in 0in 0pt;">
  <span style="font-size: small; font-family: Times New Roman;">stuff here</span>
</p>

Estoy tratando de hacer un Vim de búsqueda y reemplazo para deshacerse de todos class=""y style=""pero estoy teniendo problemas para hacer el partido ungreedy.

Mi primer intento fue este

%s/style=".*?"//g

pero a Vim no parece gustarle el ?. Desafortunadamente, eliminar el ?hace que el partido sea demasiado codicioso.

¿Cómo puedo hacer que mi pareja no sea graciosa?

Mark Biek
fuente
Creo que la respuesta de Paul es buena. Solo para decir que "?" no significa opcional en vim (si esto es lo que quiere lograr con "?")
LB40
15
@LB, en muchos idiomas,. *? significa unir cualquier personaje pero no ser codicioso. Eso es lo que está tratando de lograr.
Randy Morris el

Respuestas:

735

En lugar de .*usar .\{-}.

%s/style=".\{-}"//g

Ver también :help non-greedy

Randy Morris
fuente
38
No es muy intuitivo, ¿es algo que solo vim hace?
Ehtesh Choudhury
95
Todo tiene su propio lenguaje de expresión regular ... ese es uno de los mayores problemas con la expresión regular.
Patrick Farrell
35
Muchas de estas herramientas maduraron al mismo tiempo y desarrollaron independientemente su propio dialecto de un lenguaje de expresión regular. Muchas de estas herramientas también estaban tratando de resolver diferentes problemas, por lo que tiene sentido que la sintaxis pueda ser potencialmente enormemente diferente en estas implementaciones. Tenemos que aceptar que así es como funciona el mundo real a pesar de que a veces nos hace la vida más difícil como desarrolladores. Afortunadamente, muchas herramientas al menos proporcionan una implementación de expresiones regulares compatible con Perl en estos días. Lamentablemente, Vim no es uno de ellos.
Randy Morris
15
Si alguien como yo predetermina su búsqueda a \v(bandera muy mágica), querrá usar .{-}.
jgillman
48
@Shurane @Ziggy Mnemonic: controla el número de repeticiones como {1,3}hace (llaves). El signo menos -significa: repetir lo menos posible (poco == menos);)
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
58

La búsqueda no codiciosa en vim se realiza utilizando el operador {-}. Me gusta esto:

%s/style=".\{-}"//g

sólo inténtalo:

:help non-greedy
Vilhelm Gray
fuente
48

Qué hay de malo en

%s/style="[^"]*"//g
Paul Tomblin
fuente
77
Aunque, para mi propio beneficio, todavía me gustaría entender mejor lo desagradable.
Mark Biek
17

Si se siente más cómodo sintaxis regex PCRE, que

  1. admite el operador no codicioso ?, como lo solicitó en OP; y
  2. no requiere operadores de agrupación y cardinalidad de retroceso (un requisito de sintaxis vim completamente contraintuitivo ya que no está haciendo coincidir caracteres literales sino especificando operadores); y
  3. tienes [g] vim compilado con la función perl, prueba usando

    : ver e inspeccionar características; si + perl está ahí, estás listo para ir)

intente buscar / reemplazar usando

:perldo s///

Ejemplo. Intercambie los atributos src y alt en la etiqueta img:

<p class="logo"><a href="/"><img src="/caminoglobal_en/includes/themes/camino/images/header_logo.png" alt=""></a></p>

:perldo s/(src=".*?")\s+(alt=".*?")/$2 $1/

<p class="logo"><a href="/"><img alt="" src="/caminoglobal_en/includes/themes/camino/images/header_logo.png"></a></p>
FrDarryl
fuente
1
perldofunciona muy bien, pero desafortunadamente no resalta la prueba seleccionada al escribir la expresión regular.
mljrg
12

Descubrí que una buena solución para este tipo de preguntas es:

:%! sed ...

(o perl si lo prefieres). IOW, en lugar de aprender las peculiaridades de la expresión regular de vim, usa una herramienta que ya conoces. Usar perl haría que el? modificador de trabajo para desagrupar el partido.

William Pursell
fuente
2
buen punto, pero poder hacer /patternpara verificar que estás haciendo coincidir el patrón correctamente antes de aplicarlo y usar el cmodificador en tu expresión regular vim también es bueno :)
João Portela
esto es correcto. ¡Todas las soluciones aquí no son cercanas a las no codiciosas! si tiene que hacer coincidir [0-9] \ {7} en una línea con mucho texto y varias ocurrencias de ese patrón, aquí no habrá solución. Las soluciones aquí solo funcionan para cosas simples (que para ser justos, es lo que se pidió). pero si está haciendo un poco más que buscar hasta la próxima cita, vim no lo ayudará.
gcb
4

Con \v(como se sugiere en varios comentarios)

:%s/\v(style|class)\=".{-}"//g
JJoao
fuente
2

El complemento eregex.vim maneja operadores no codiciosos de estilo Perl *?y+?

baño
fuente
@xsilenT github.com/othree/eregex.vim : "Se recomienda instalar el script usando Vundle o patógeno".
eXe
lo siento, no sé cómo usar Vundle o patógeno.
xsilen T
-4

G'day

El procesamiento de expresiones regulares de Vim no es demasiado brillante. Descubrí que la sintaxis regexp para sed es la combinación adecuada para las capacidades de vim.

Por lo general, configuro el resaltado de búsqueda en (: establecer hlsearch) y luego juego con la expresión regular después de ingresar una barra para ingresar al modo de búsqueda.

Editar: Mark, ese truco para minimizar la correspondencia codiciosa también está cubierto en el excelente libro de Dale Dougherty "Sed & Awk" ( enlace de Amazon desinfectado ).

El Capítulo Tres "Comprensión de la sintaxis de expresiones regulares" es una excelente introducción a las capacidades de expresión regular más primitivas involucradas con sed y awk. Solo una lectura corta y muy recomendable.

HTH

salud,

Rob Wells
fuente
77
El procesamiento de expresiones regulares de Vim es bastante agradable. Puede hacer cosas que no puede, como la coincidencia en los números de línea / columna o la coincidencia basada en la clasificación de caracteres por idioma como palabras clave o identificadores o espacios en blanco. También tiene aserciones de ancho cero y la capacidad de poner expresiones en el lado derecho de un reemplazo. Si lo usa \v, ayuda a limpiar mucho la sintaxis.
Brian Carper
1
@Brian, saludos. Haré una ayuda regex y veré lo que me he estado perdiendo.
Rob Wells
@RobWells, Sed & Awk , que de hecho es un muy buen libro en mi humilde opinión, no gasta explícitamente ninguna palabra en cuantificadores codiciosos / perezosos. Como prueba, no hay absolutamente ninguna ocurrencia de las palabras codicia o avaricia en el libro, y solo hay una, pero no relacionada, ocurrencia de la palabra perezoso .
Enrico Maria De Angelis
@EnricoMariaDeAngelis es, pero el ejemplo no se refiere al término explícitamente. Se trata de cómo adaptar su expresión regular para usar el operador "no" para lograr coincidencias no codiciosas. El término codicioso y perezoso llegó con el motor NFA de Perl cuando presentaron a los operadores para modificar específicamente el comportamiento de coincidencia codiciosa.
Rob Wells