Expressões regulares são uma ferramenta poderosa no arsenal de programadores, mas - existem alguns casos em que não são a melhor opção ou são totalmente prejudiciais.
O exemplo simples nº 1 é analisar o HTML com o regexp - um caminho conhecido para vários bugs. Provavelmente, isso também atribui à análise em geral.
Mas existem outras áreas claramente proibidas para expressões regulares?
ps: " A pergunta que você está fazendo parece subjetiva e provavelmente será encerrada. " - portanto, quero enfatizar que estou interessado em exemplos em que o uso de regexps é conhecido por causar problemas.
Respostas:
Não use expressões regulares:
Isso não se limita ao HTML . Um XML válido simples não pode ser razoavelmente analisado com uma expressão regular, mesmo que você conheça o esquema e saiba que ele nunca será alterado.
Não tente, por exemplo, analisar o código fonte do C # . Analise-o para obter uma estrutura de árvore significativa ou os tokens.
E se você precisar procurar uma letra, pequena e maiúscula? Se você gosta de expressões regulares, você as usará. Mas não é mais fácil / rápido / legível usar duas pesquisas, uma após a outra? Provavelmente, na maioria dos idiomas, você obterá melhor desempenho e tornará seu código mais legível.
Por exemplo, o código de exemplo na resposta do Ingo é um bom exemplo quando você não deve usar expressões regulares. Basta procurar
foo
e depoisbar
.Um bom exemplo é um filtro de obscenidade. Não é apenas uma má idéia, em geral, implementá-lo, mas você pode ser tentado a fazê-lo usando expressões regulares, e você o fará errado. Há muitas maneiras pelas quais um humano pode escrever uma palavra, um número, uma frase e será entendido por outro humano, mas não pela sua expressão regular. Então, em vez de capturar uma verdadeira obscenidade, sua expressão regular passará o tempo dela prejudicando outros usuários.
Por exemplo, não valide um endereço de email por meio de uma expressão regular. Na maioria dos casos, você fará errado. Em um caso raro, você fará tudo certo e terminará com um horror de codificação de 6 343 caracteres .
Sem as ferramentas certas, você cometerá erros. E você os notará no último momento, ou talvez nunca. Se você não se importa com código limpo, escreverá uma sequência de vinte linhas sem comentários, sem espaços, sem novas linhas.
Sério, se eu pegar o seu código e precisar revisá-lo ou modificá-lo, não quero passar uma semana tentando entender uma sequência de vinte linhas com muitos símbolos.
fonte
(?(DEFINE))
asserções;) muito semelhante ao que você escreveria em yacc ou equivalente;)"<a href='foo'>stuff</a>"
. Regexes modernos não têm problemas com isso.O mais importante: quando o idioma que você está analisando não é regular .
O HTML não é uma linguagem comum e não é possível analisá-lo com uma expressão regular (não apenas difícil ou um caminho para o código de buggy).
fonte
No stackoverflow, muitas vezes vemos pessoas solicitarem expressões regulares que descubram se uma determinada string não contém isto ou aquilo. Isto é, IMHO, invertendo o objetivo da expressão regular. Mesmo que exista uma solução (empregando asserções negativas por trás do objeto ou algo assim), muitas vezes é muito melhor usar o regex para o que foi feito e lidar com o caso negativo com a lógica do programa.
Exemplo:
fonte
Dois casos:
Quando existe uma maneira mais fácil
A maioria dos idiomas fornece uma função simples como INSTR para determinar se uma sequência é um subconjunto de outra. Se é isso que você deseja fazer, use a função mais simples. Não escreva sua própria expressão regular.
Se houver uma biblioteca disponível para executar uma manipulação complexa de cadeias, use-a em vez de escrever sua própria expressão regular.
Quando expressões regulares não são suficientemente poderosas
fonte
Expressões regulares não podem identificar estruturas recursivas . Essa é a limitação fundamental.
Pegue o JSON - é um formato bastante simples, mas como um objeto pode conter outros objetos como valores de membros (arbitrariamente profundos), a sintaxe é recursiva e não pode ser analisada por uma regex. Por outro lado, o CSV pode ser analisado por expressões regulares, uma vez que não contém estruturas recursivas.
Em resumo, expressões regulares não permitem que o padrão se refira a si próprio. Você não pode dizer: neste ponto da sintaxe, corresponda a todo o padrão novamente. Dito de outra forma, as expressões regulares correspondem apenas linearmente, não contém uma pilha que permita acompanhar a profundidade de um padrão aninhado.
Observe que não tem nada a ver com a complexidade ou complexidade do formato. As expressões S são realmente muito simples, mas não podem ser analisadas com uma regex. CSS2, por outro lado, é uma linguagem bastante complexa, mas não contém estruturas recursivas e, portanto, pode ser analisada com um regex. (Embora isso não seja verdade para CSS3 devido a expressões CSS, que possuem uma sintaxe recursiva.)
Portanto, não é porque é feio ou complexo ou propenso a erros analisar o HTML usando apenas regex. É que simplesmente não é possível .
Se você precisar analisar um formato que contenha estruturas recursivas, precisará pelo menos complementar o uso de expressões regulares com uma pilha para acompanhar o nível de estruturas recursivas. Normalmente, é assim que um analisador funciona. Expressões regulares são usadas para reconhecer as partes "lineares", enquanto o código personalizado fora da regex é usado para acompanhar as estruturas aninhadas.
Normalmente, a análise como essa é dividida em fases separadas. Tokenização é a primeira fase em que expressões regulares são usadas para dividir a entrada em uma sequência de "tokens", como palavras, pontuação, colchetes, etc. A análise é a próxima fase em que esses tokens são analisados em uma estrutura hierárquica, uma árvore de sintaxe.
Portanto, quando você ouvir que HTML ou C # não podem ser analisados por expressões regulares, lembre-se de que expressões regulares ainda são uma parte crítica dos analisadores. Você simplesmente não pode analisar esse idioma usando apenas expressões regulares e nenhum código auxiliar.
fonte