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?

Mark Biek
fonte
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
Relacionado: Como fazer com que os regex não sejam gananciosos? no Vim SE.
Big McLargeHuge

Respostas:

734

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

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

Veja também :help non-greedy

Randy Morris
fonte
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
Vilhelm Grey
fonte
48

O que há de errado com

%s/style="[^"]*"//g
Paul Tomblin
fonte
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>
FrDarryl
fonte
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.

William Pursell
fonte
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
JJoao
fonte
2

O plug-in eregex.vim lida com operadores não gananciosos no estilo Perl *?e+?

banho
fonte
@xsilenT github.com/othree/eregex.vim : "É recomendável instalar o script usando o Vundle ou o pathogen."
eXe
desculpe por não saber como usar o Vundle ou o patógeno.
xsilen T
-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,

Rob Wells
fonte
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