Regex para desenvolvedores
-
09-06-2019 - |
Pergunta
Estou tentando descobrir um regex que me permita pesquisar uma string específica enquanto pulo automaticamente os comentários.Alguém tem uma RE assim ou conhece alguma?Nem precisa ser sofisticado o suficiente para pular #if 0
blocos;Eu só quero que isso pule //
e /*
blocos.O inverso, que é apenas pesquisar dentro de blocos de comentários, também seria muito útil.
Ambiente:VS 2003
Solução
Este é um problema mais difícil do que pode parecer à primeira vista, já que você precisa considerar tokens de comentários dentro de strings, tokens de comentários que são comentados, etc.
Eu escrevi um analisador de strings e comentários para C#, deixe-me ver se consigo descobrir algo que possa ajudar...Vou atualizar se encontrar alguma coisa.
EDITAR:...ok, então encontrei meu antigo projeto 'codemasker'.Acontece que fiz isso em etapas, não com um único regex.Basicamente, procuro um arquivo de origem em busca de tokens iniciais; quando encontro um, procuro um token final e mascarei tudo o que está entre eles.Isso leva em consideração o contexto do token inicial...se você encontrar um token para "início da string", poderá ignorar com segurança os tokens de comentários até encontrar o final da string e vice-versa.Depois que o código estiver mascarado (usei guias como máscaras e uma tabela hash para controlar), você poderá pesquisar e substituir com segurança e, finalmente, restaurar o código mascarado.
Espero que ajude.
Outras dicas
Tenha especial cuidado com cordas.Strings geralmente têm sequências de escape que você também deve respeitar enquanto encontra o final delas.
Então, por exemplo. "This is \"a test\""
.Você não pode procurar cegamente por aspas duplas para encerrar.Também tome cuidado com ``"This is \"`, que mostra que você não pode simplesmente dizer "a menos que aspas duplas sejam precedidas por uma barra invertida."
Em resumo, faça alguns testes unitários brutais!
Um regexp não é a melhor ferramenta para o trabalho.
Perguntas frequentes sobre Perl:
Comentários C:
#!/usr/bin/perl
$/ = undef;
$_ = <>;
s#/\*[^*]*\*+([^/*][^*]*\*+)*/|([^/"']*("[^"\\]*(\\[\d\D][^"\\]*)*"[^/"']*|'[^'\\]*(\\[\d\D][^'\\]*)*'[^/"']*|/+[^*/][^/"']*)*)#$2#g;
print;
Comentários em C++:
#!/usr/local/bin/perl
$/ = undef;
$_ = <>;
s#//(.*)|/\*[^*]*\*+([^/*][^*]*\*+)*/|"(\\.|[^"\\])*"|'(\\.|[^'\\])*'|[^/"']+# $1 ? "/*$1 */" : $& #ge;
print;
Eu faria uma cópia e retiraria os comentários primeiro, depois pesquisaria a string da maneira normal.