Como posso tornar minha partida não gananciosa no vim?


480

Eu tenho um grande arquivo HTML com muitas marcações assim:

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

Eu estou tentando fazer um Vim pesquisa e substituição para se livrar de tudo class=""e style=""mas estou tendo problemas para fazer o jogo ungreedy.

Minha primeira tentativa foi essa

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

mas Vim não parece gostar do ?. Infelizmente, remover o ?jogo torna a partida muito gananciosa.

Como posso tornar a minha partida desagradável?


Eu acho que a resposta de Paul é boa. Só para dizer que "?" faz opcional não média no vim (se é isso que você quer alcançar usando "?")
LB40

15
@LB, em vários idiomas,. *? significa combinar com qualquer caractere, mas não ser ganancioso. É isso que ele está tentando alcançar.
Randy Morris

Respostas:


734

Em vez de .*usar .\{-}.

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

Veja também :help non-greedy


38
Não é muito intuitivo, isso é algo que apenas o vim faz?
Ehtesh Choudhury

95
Tudo tem sua própria linguagem de expressão regular ... esse é um dos maiores problemas do regex.
22813 Patrick Farrell

35
Muitas dessas ferramentas amadureceram na mesma época e desenvolveram independentemente seu próprio dialeto de uma linguagem de expressão regular. Muitas dessas ferramentas também estavam tentando resolver problemas diferentes, portanto, faz sentido que a sintaxe possa ser potencialmente muito diferente entre essas implementações. Temos que aceitar que é assim que o mundo real funciona, embora às vezes torne nossas vidas mais difíceis como desenvolvedores. Felizmente, muitas ferramentas pelo menos fornecem uma implementação de regex compatível com Perl atualmente. Infelizmente o Vim não é um deles.
Randy Morris

15
Se alguém como eu padronizar sua pesquisa para \v(bandeira muito mágica), você precisará usar .{-}.
jgillman

48
@Shurane @Ziggy Mnemonic: controla o número de repetições como {1,3}faz (chaves). O sinal de menos -meios: Repetir o mínimo possível (pouco == menos);)
Ciro Santilli郝海东冠状病六四事件法轮功

58

A pesquisa não gananciosa no vim é feita usando o operador {-}. Como isso:

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

apenas tente:

:help non-greedy

48

O que há de errado com

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

7
Embora, para meu próprio benefício, eu ainda gostaria de entender melhor a coisa não-gulosa.
Mark Biek

17

Se você estiver mais confortável com a sintaxe PCRE regex, que

  1. suporta o operador não ganancioso?, como você pediu no OP; e
  2. não requer operadores de agrupamento e cardinalidade em retrocesso (um requisito de sintaxe totalmente contra-intuitivo do vim, pois você não está correspondendo caracteres literais, mas especificando operadores); e
  3. você [v] compilou com o recurso perl, teste usando

    : ver e inspecionar recursos; se + perl está aí, você está pronto para ir)

tente pesquisar / substituir usando

:perldo s///

Exemplo. Troque os atributos src e alt na tag 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 muito bem, mas infelizmente não destaca o teste selecionado ao digitar o regex.
mljrg

12

Eu descobri que uma boa solução para esse tipo de pergunta é:

:%! sed ...

(ou perl, se você preferir). IOW, em vez de aprender as peculiaridades de regex do vim, use uma ferramenta que você já conhece. Usar perl faria o? trabalho modificador para ungreedy a partida.


2
bom ponto, mas poder fazer isso /patternpara verificar se você está correspondendo corretamente ao padrão antes de aplicá-lo e usar o cmodificador em sua expressão regular do vim também é bom :)
João Portela

isto está correto. todas as soluções aqui não são nem um pouco gananciosas! se você precisar combinar [0-9] \ {7} em uma linha com muito texto e várias ocorrências desse padrão, nenhuma solução aqui será suficiente. As soluções aqui funcionam apenas para coisas simples (o que é justo, é o que foi solicitado). mas se você estiver fazendo um pouco mais do que pesquisar até a próxima citação, o vim não ajudará.
gcb

4

With \v(como sugerido em vários comentários)

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


-4

G'day,

O processamento regexp do Vim não é muito brilhante. Descobri que a sintaxe regexp para sed é a combinação certa para os recursos do vim.

Normalmente, defino o destaque de pesquisa em (: defina hlsearch) e depois jogo com o regexp depois de inserir uma barra para entrar no modo de pesquisa.

Edit: Mark, esse truque para minimizar a correspondência gananciosa também é abordado no excelente livro de Dale Dougherty, "Sed & Awk" ( link higienizado da Amazon ).

O capítulo três, "Entendendo a sintaxe da expressão regular", é uma excelente introdução aos recursos de regexp mais primitivos envolvidos no sed e no awk. Apenas uma leitura curta e altamente recomendada.

HTH

Felicidades,


7
O processamento regex do Vim é realmente muito bom. Ele pode fazer coisas que o sed não pode, como coincidir com números de linha / coluna ou com base na classificação de caracteres por idioma como palavras-chave ou identificadores ou espaço em branco. Ele também possui asserções de largura zero e a capacidade de colocar expressões no lado direito de uma substituição. Se você o usar \v, ajudará a limpar bastante a sintaxe.
Brian Carper

1
@ Brian, felicidades. Vou fazer uma regex de ajuda e ver o que estou perdendo.
22420 Rob Wells

O @RobWells, Sed & Awk , que é realmente um ótimo livro, não gasta explicitamente nenhuma palavra em quantificadores gananciosos / preguiçosos. Como prova, não há absolutamente nenhuma ocorrência das palavras ganância ou ganância no livro, e há apenas uma ocorrência, mas não relacionada, da palavra preguiçoso .
Enrico Maria De Angelis

@EnricoMariaDeAngelé é, mas o exemplo não se refere ao termo explicitamente. É sobre como adaptar seu regex para usar o operador "not" para obter correspondências não gananciosas. O termo ganancioso e preguiçoso chegou com o mecanismo NFA do Perl quando eles introduziram operadores para modificar especificamente o comportamento de correspondência ganancioso.
Rob Wells
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.