Como ativar regex estendido (Extended REGEX) no VIM

Ficar escapando caracteres que deveriam ter significados especiais no regex pode ser muito chato. Mas o VIM tem um recurso interessante chamado very magic! Veja como utilizá-lo.

Tempo estimado de leitura: 5 minutos

Introdução

De forma geral, há formas bem menos insanas de se criar expressões regulares do que dentro do VIM. E é por isso que você pode querer utilizar outras ferramentas para testar, validar e só depois importar sua regex no editor de textos.

Economize tempo com um bom testador

Um testador de regex bem interessantes é o regex101.com, que auxilia muito na hora de compor uma expressão enorme. Há outros bem legais, mas esse é meu preferido.

Depois que você chega na expressão perfeita, descobre no VIM que agora precisa sair escapando caracteres que não deveriam ser literais! E depois, ainda tem que transformá-los em especiais para que tudo funcione…

Mas há uma ótima solução, que consiste em chamar uma opção interna chamada very magic, que vai ajudar muito a evitar escapar montes de ( { } ) em expressões regulares longas.

Very Magic!

Então, para usar o very magic, basta inserir um comando adicional antes da expressão regular: \v

Num exemplo simples e sem criatividade 😆, casamos o grupo 1 (Magia) e depois trazemos ele de volta com \1, acrescentando very magic, ignorando qualquer outra coisa que não esteja casada nesta expressão.

#sem very magic
:%s/\v\(Magia\) furta-cor/\1 very magic/g

#com very magic
:%s/\v(Magia) furta-cor/\1 very magic/g

Até aqui, tudo bem. Não parece atrapalhar muito. Mas vamos a um exemplo mais longo, no qual não usar very magic pode ser um problema real.

Temos 6 campos em uma listagem de produtos e precisamos fazer algumas substituições e inserções de linhas e dados para encaixar num arquivo .txt de geração de NFe da Sefaz.

1|9388552610010|Item A|44.0000|10.0404545455|441.78
2|9488542618041|Item B|3.0000|14.0980000000|70.49
3|9588532619058|Item C|41.0000|4.9614285714|69.46
4|9583522613157|Item D|9.0000|4.5585714286|223.37
5|9588122623188|Item E|18.0000|4.8527777778|87.35
6|9384562634201|Item F|14.0000|28.2492857143|395.49
7|9285562614225|Item G|17.0000|10.7370588235|182.53
8|9186562647232|Item H|8.0000|3.2850000000|26.28
9|9280562617256|Item I|36.0000|125.0611111111|4502.20
10|9188552617270|Item J|14.0000|15.4914285714|216.88
11|9178552627324|Item K|17.0000|5.2288235294|88.89

A lista foi inserida no textador do regex101.com, perfeita, todos os campos casados.

Se colocar direto no VIM, simplesmente não irá funcionar. Veja como deveria ficar, sem usar o \v very magic:

#sem very magic, lotado de escapes

:%s~^\(\d+\)\|\(\d\{13\}\)\|\(.*\)\|\(\d+\.\d\{4\}\)\|\(\d+\.\d\{10\}\)\|\(\d+\.\d\{2\}\)$~H|\1||\rI|\2||\3|49019900||5102|un|\4\|\5|\6||un|\4|\5|||||1|||||||\rM||\rN|\rN10d|0|103|\rO||||999|\rO07|99|0.00|\rO11|0.0000|0.0000|\rQ|\rQ04|07|\rS|\rS04|07|~g

Agora, com \v

#com very magic, mais legível, (mais) compatível com outros robôs de regex, como o do regex101, do sed -E etc

:%s~\v^(\d+)\|(\d{13})\|(.*)\|(\d+\.\d{4})\|(\d+\.\d{10})\|(\d+\.\d{2})$~H|\1||\rI|\2||\3|49019900||5102|un|\4\|\5|\6||un|\4|\5|||||1|||||||\rM||\rN|\rN10d|0|103|\rO||||999|\rO07|99|0.00|\rO11|0.0000|0.0000|\rQ|\rQ04|07|\rS|\rS04|07|~g

Observação: os retrovisores de grupos em diversos mecanismos de regex geralmente são chamados com $: $1 $2 $3, mas no VIM é \1 \2 \3

Para não esbarrar nos problemas do very magic e aproveitar somente a parte boa, há uma coisa importante a se saber: diversos caracteres que não têm significado especial em outros robôs de regex, passam a ter aqui, no VIM.

Utilizando \v, alguns caracteres bem esquisitos passam a ter significado especial, como @ % & ~. Portanto, caso precise deles como literal, escape com \

@%&~

:%s/\v\@\%\&\~

Automatizando o very magic

Infelizmente não é possível setar a opção very magic no .vimrc. Você terá mesmo que aplicar o \v individualmente em todas as regex que você montar. Você pode mapear a combinação /s para gerar um /s\v automaticamente com acrescentando o cnoremap no seu ~/.vimrc (agradecimento ao colega Micael Levi pela dica na excelente comunidade de Expressões Regulares do Telegram).

 " Mapeia s/ para /s\v
 cnoremap s/ s/\v

” Mapeia /s para /s\v
cnoremap s/ s/\v

Saiba tudo sobre o very magic e outras opções magic no :help do VIM

:help magic

(...) Use of "\v" means that after it, all ASCII characters except '0'-'9', 'a'-'z', 'A'-'Z' and '_' have special meaning: "very magic"

Dúvidas, sugestões? Bota nos comentários!

Veja também

Sobre o autor

bureau-it.com