¿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?


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


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

48

Qué hay de malo en

%s/style="[^"]*"//g

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>

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.


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


-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,


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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.