Ao explorar expressões regulares (também conhecidas como RegEx-es), muitas pessoas parecem ver expressões regulares como o Santo Graal. Algo que parece tão complicado - só deve ser a resposta para qualquer pergunta. Eles tendem a pensar que todo problema é solucionável usando expressões regulares.
Por outro lado, também existem muitas pessoas que tentam evitar expressões regulares a todo custo. Eles tentam encontrar uma maneira de contornar expressões regulares e aceitam codificação adicional apenas por isso, mesmo que uma expressão regular seja uma solução mais compacta.
Por que as expressões regulares são consideradas tão controversas? Existem mal-entendidos generalizados sobre como eles funcionam? Ou poderia ser uma crença ampla de que expressões regulares são geralmente lentas?
Respostas:
Não acho que as pessoas se oponham a expressões regulares porque são lentas, mas porque são difíceis de ler e escrever, além de difíceis de acertar. Embora existam algumas situações em que expressões regulares fornecem uma solução eficaz e compacta para o problema, às vezes elas são colocadas em situações em que é melhor usar uma seção de código fácil de ler e sustentável.
fonte
|
ou.*
), porque eles usam uma máquina de empilhar e voltar atrás. É por isso que você precisa ajustar cuidadosamente suas expressões regulares em Perl, Java, Python, Ruby ... Mecanismos de expressão regular à moda antiga (emgrep
, por exemplo) primeiro compilam o padrão em um DFA. Posteriormente, a complexidade do padrão é amplamente irrelevante. Acabei de usar Java e grep para o mesmo texto e padrão: 22min vs 2s. Aqui está a ciência: swtch.com/~rsc/regexp/regexp1.htmlTornando Regexes Mantíveis
Um grande avanço para desmistificar os padrões anteriormente referidos como "expressões regulares" é o
/x
sinalizador de regex do Perl - às vezes escrito(?x)
quando incorporado - que permite espaço em branco (quebra de linha, recuo) e comentários. Isso melhora seriamente a legibilidade e, portanto, a capacidade de manutenção. O espaço em branco permite a divisão cognitiva, para que você possa ver quais grupos com o que.Agora, os padrões modernos agora suportam tanto referências retrospectivas relativamente numeradas quanto nomeadas. Isso significa que você não precisa mais contar grupos de captura para descobrir que precisa
$4
ou\7
. Isso ajuda na criação de padrões que podem ser incluídos em outros padrões.Aqui está um exemplo de um grupo de captura relativamente numerado:
E aqui está um exemplo da abordagem superior das capturas nomeadas:
Regexes gramaticais
O melhor de tudo é que essas capturas nomeadas podem ser colocadas em um
(?(DEFINE)...)
bloco, para que você possa separar a declaração da execução de elementos nomeados individuais de seus padrões. Isso os faz agir como sub-rotinas dentro do padrão.Um bom exemplo desse tipo de "regex gramatical" pode ser encontrado nesta resposta e nesta . Eles se parecem muito mais com uma declaração gramatical.
Como o último lembra você:
Isso não pode ser enfatizado demais. Obviamente, se você não usar essas coisas em seus padrões, muitas vezes criará um pesadelo. Mas se você os usar, não precisará.
Aqui está outro exemplo de um padrão gramatical moderno, este para analisar o RFC 5322: use 5.10.0;
Isso não é notável - e esplêndido? Você pode pegar uma gramática no estilo BNF e traduzi-la diretamente em código sem perder sua estrutura fundamental!
Se os padrões gramaticais modernos ainda não são suficientes para você, o
Regexp::Grammars
módulo brilhante de Damian Conway oferece uma sintaxe ainda mais limpa, com depuração superior também. Aqui está o mesmo código para analisar a reformulação da RFC 5322 em um padrão desse módulo:Há muitas coisas boas na página de manual do perlre , mas essas melhorias drásticas nos recursos fundamentais de design de regex não se limitam de maneira alguma apenas ao Perl. De fato, a página de manual do pcrepattern pode ser uma leitura mais fácil e abrange o mesmo território.
Os padrões modernos não têm quase nada em comum com as coisas primitivas que você aprendeu em sua aula finita de autômatos.
fonte
/x
. É usar as expressões regulares gramaticalmente, com(?&name)
sub-rotinas internas de expressões regulares, que realmente fazem isso brilhar.re.VERBOSE
bandeira.Os expressões regulares são uma ótima ferramenta, mas as pessoas pensam "Ei, que ótima ferramenta, eu vou usá-la para fazer o X!" onde X é algo para o qual uma ferramenta diferente é melhor (geralmente um analisador). É o padrão usando um martelo em que você precisa de um problema de chave de fenda.
fonte
split($pattern,$string)
vsexplode($delimiter,$string)
- felizmente o primeiro está sendo depreciado, mas muito código usou o primeiro quando eles só precisavam do poder do posterior. Aggreed, RegEx de fornecer uma ferramenta fácil de fazer algumas coisas, mas a menos que você precisa do poder cheio de expressões regulares elesQuase todo mundo que conheço que usa expressões regulares regularmente (trocadilhos) vem de um ambiente Unix-ish, onde usa ferramentas que tratam REs como construções de programação de primeira classe, como grep, sed, awk e Perl. Como quase não há sobrecarga sintática para usar uma expressão regular, sua produtividade aumenta muito quando o fazem.
Por outro lado, os programadores que usam linguagens nas quais os REs são uma biblioteca externa tendem a não considerar o que expressões regulares podem trazer para a tabela. O programador "tempo-custo" é tão alto que: a) os REs nunca apareceram como parte de seu treinamento; ou b) eles não "pensam" em termos de ERs e preferem recorrer a padrões mais familiares.
fonte
Expressões regulares permitem gravar uma máquina de estado finito (FSM) personalizada de maneira compacta, para processar uma sequência de entradas. Há pelo menos duas razões pelas quais é difícil usar expressões regulares:
O desenvolvimento de software da velha escola envolve muito planejamento, modelos de papel e reflexão cuidadosa. As expressões regulares se encaixam muito bem nesse modelo, porque escrever uma expressão eficaz de maneira adequada envolve muito olhar para ele, visualizando os caminhos do FSM.
Os desenvolvedores de software modernos preferem elaborar códigos e usar um depurador para executar a execução, para verificar se o código está correto. Expressões regulares não suportam esse estilo de trabalho muito bem. Uma "execução" de uma expressão regular é efetivamente uma operação atômica. É difícil observar a execução gradual em um depurador.
É muito fácil escrever uma expressão regular que aceite acidentalmente mais informações do que você pretende. O valor de uma expressão regular não é realmente para corresponder a entrada válida, é para não corresponder a entrada inválida . As técnicas para realizar "testes negativos" para expressões regulares não são muito avançadas ou, pelo menos, pouco utilizadas.
Isso vai ao ponto de as expressões regulares serem difíceis de ler. Apenas olhando para uma expressão regular, é preciso muita concentração para visualizar todas as entradas possíveis que devem ser rejeitadas, mas são aceitas por engano. Já tentou depurar o código de expressão regular de outra pessoa ?
Se há resistência ao uso de expressões regulares entre os desenvolvedores de software hoje, acho que isso se deve principalmente a esses dois fatores.
fonte
As pessoas tendem a pensar que expressões regulares são difíceis; mas é porque eles estão usando errado. Escrever linhas complexas sem comentários, recuos ou capturas nomeadas. (Você não empacota sua expressão SQL complexa em uma linha, sem comentários, recuo ou alias, não é?). Então, sim, para muitas pessoas, elas não fazem sentido.
No entanto, se o seu trabalho tem alguma coisa a ver com a análise de texto (praticamente qualquer aplicativo da Web disponível ...) e você não conhece expressões regulares, é péssimo no seu trabalho e está desperdiçando seu próprio tempo e o do seu Empregador. Existem excelentes recursos para ensinar tudo sobre eles que você precisa conhecer e muito mais.
fonte
x
modificador para expressões regulares que faz com que o espaço em branco seja ignorado. Isso permite que você coloque o regex em algumas linhas e adicione comentários.re.X
conhecido comore.VERBOSE
.x
modificador em tcl. Eu acredito que é bastante padrão, já que o tcl, ao contrário de outros idiomas, não usa o PCRE.Como eles não possuem a ferramenta de aprendizado mais popular nos IDEs comumente aceitos: Não há Assistente de Regex. Nem mesmo preenchimento automático. Você precisa codificar a coisa toda sozinho.
fonte
()
, quadrados[]
ou encaracolados{}
. Também funcionará com a barra invertida." Expressões regulares: agora você tem dois problemas " é um ótimo artigo de Jeff Atwood sobre o assunto. Basicamente, expressões regulares são "difíceis"! Eles podem criar novos problemas. Eles são eficazes, no entanto.
fonte
Eu não acho que eles sejam tão controversos.
Também acho que você meio que respondeu à sua própria pergunta, porque aponta como seria tolo usá-las em qualquer lugar ( nem tudo é uma linguagem comum 2 ) ou para evitar usá-las. Você, o programador, precisa tomar uma decisão inteligente sobre quando expressões regulares ajudarão ou danificarão o código. Quando confrontados com essa decisão, duas coisas importantes a serem lembradas são a manutenção (que implica legibilidade) e a extensibilidade.
Para aqueles que são particularmente avessos a eles, meu palpite é que eles nunca aprenderam a usá-los adequadamente. Eu acho que a maioria das pessoas que passa apenas algumas horas com um tutorial decente as descobre e se torna fluente muito rapidamente. Aqui está minha sugestão de onde começar:
http://docs.python.org/howto/regex
Embora essa página fale sobre expressões regulares no contexto do Python, descobri que as informações são muito aplicáveis em outros lugares. Existem algumas coisas que são específicas do Python, mas acredito que elas são claramente anotadas e fáceis de lembrar.
fonte
Expressões regulares são para strings o que são operadores aritméticos para números, e eu não os consideraria controversos. Eu acho que mesmo um ativista de OO bastante militante como eu (que tenderia a escolher outros objetos em vez de cordas) teria dificuldade em rejeitá-los.
fonte
O problema é que as expressões regulares são potencialmente tão poderosas que você pode fazer coisas com elas para as quais deve usar algo diferente.
Um bom programador deve saber onde usá-los e onde não. O exemplo típico é analisar idiomas não regulares (consulte Decidindo se um idioma é regular ).
Eu acho que você não pode dar errado se, a princípio, se restringir a expressões regulares reais (sem extensões). Algumas extensões podem facilitar sua vida, mas se você encontrar algo difícil de expressar como uma regex real , isso pode ser uma indicação de que uma regex não é a ferramenta certa.
fonte
Você quase pode estar se perguntando por que ir ao cinema é controverso.
Basicamente, quando você obtém tanto poder "óbvio", as pessoas tendem a abusar delas em situações para as quais não são a melhor opção. O número de pessoas que pedem para analisar CSVs ou XML ou HTML em expressões regulares, por exemplo, me surpreende. É a ferramenta errada para o trabalho. Mas alguns usuários insistem em usar expressões regulares de qualquer maneira.
Pessoalmente, tento encontrar esse meio-termo feliz - use expressões regulares para o que elas servem e evite-as quando estiverem abaixo do ideal.
Observe que as expressões regulares ainda podem ser usadas para analisar CSVs, XML, HTML, etc. Mas geralmente não em uma única expressão regular.
fonte
Não acho que "controverso" seja a palavra certa.
Mas já vi vários exemplos em que as pessoas dizem "qual é a expressão regular que preciso para fazer uma manipulação dessas e de cordas?" que são problemas XY.
Em outras palavras, eles começaram com a suposição de que um regex é o que eles precisam, mas seria melhor com um split (), uma tradução como tr /// do perl, onde os caracteres são substituídos um pelo outro, ou apenas um índice ().
fonte
Este é um assunto interessante.
Muitos aficionados por expressão regular parecem confundir a concisão da fórmula com eficiência.
Além disso, um regexp que requer muito pensamento produz para seu autor uma satisfação maciça que o torna legítimo imediatamente.
Mas ... regexps são tão convenientes quando o desempenho não é um problema e você precisa lidar rapidamente com uma saída de texto, no Perl, por exemplo. Além disso, enquanto o desempenho é um problema, pode-se preferir não tentar vencer a biblioteca regexp usando um algoritmo caseiro que pode ser com erros ou menos eficiente.
Além disso, existem várias razões pelas quais os regexps são injustamente criticados, por exemplo
fonte
O que eu acho que é Aprender Regex e manter o Regex impopular, a maioria dos desenvolvedores é preguiçosa ou a maioria deles depende de bibliotecas externas para fazer a análise por eles ... eles confiam no Google para obter a resposta e até pedem nos fóruns para o código completo para o problema deles. Mas quando se trata de implementar ou modificar / manter um regex, eles simplesmente falham.
Existe um ditado popular "Amigos não permitem que amigos usem Regex para analisar HTML"
Mas, no que me diz respeito, criei analisadores HTML completos usando o Regex e acho que o regex é melhor na análise de strings html tanto em termos de velocidade quanto de memória (se você tem uma idéia do que deseja obter :))
fonte
Expressões regulares são um mistério sério para muitas pessoas, inclusive eu. Funciona muito bem, mas é como olhar para uma equação matemática. Fico feliz em informar que alguém finalmente criou um local consolidado de várias funções de expressão regular em http://regexlib.com/ . Agora, se a Microsoft criar apenas uma classe de expressão regular, executará automaticamente muitas das coisas comuns, como eliminação de letras ou filtragem de datas.
fonte
Acho expressões regulares inestimáveis às vezes. Quando eu preciso fazer algumas pesquisas "difusas", e talvez substitua. Quando os dados podem variar e ter uma certa aleatoriedade. No entanto, quando preciso fazer uma pesquisa e substituição simples ou procurar uma sequência, não uso expressões regulares. Embora eu conheça muitas pessoas que o fazem, elas o usam para tudo. Essa é a controvérsia.
Se você quiser colocar uma tacha na parede, não use um martelo. Sim, vai funcionar, mas quando você pegar o martelo, eu poderia colocar 20 tachinhas na parede.
Expressões regulares devem ser usadas para o que elas foram projetadas e nada menos.
fonte
Embora eu ache que as expressões regulares sejam uma ferramenta essencial, a coisa mais irritante sobre elas é que existem implementações diferentes. Pequenas diferenças de sintaxe, modificadores e, especialmente, "ganância" podem tornar as coisas realmente caóticas, exigindo tentativa e erro e às vezes gerando bugs intrigantes.
fonte
Em alguns casos, acho que você precisa usá-los. Por exemplo, para construir um lexer.
Na minha opinião, este é um ponto de vista de pessoas que podem escrever regexp e pessoas que não (ou dificilmente). Pessoalmente, acho que é bom, por exemplo, validar a entrada de um formulário, seja em javascript para avisar o usuário ou em linguagem do servidor.
fonte
Eu acho que é uma técnica menos conhecida entre os programadores. Portanto, não há uma ampla aceitação por isso. E se você tiver um gerente não técnico para revisar seu código ou revisar seu trabalho, uma expressão regular será muito ruim. Você passará horas escrevendo uma expressão regular perfeita e receberá algumas notas para o módulo pensando que ele / ela escreveu poucas linhas de código. Além disso, como já foi dito, ler expressões regulares é uma tarefa muito difícil.
fonte
Sistemas decentes de expressão regular, como os usados no lex e no yacc para definição do compilador, são bons, muito úteis e limpos. Nesses sistemas, os tipos de expressão são definidos em termos de outros. São as expressões regulares gigantes de uma linha ilegíveis, horríveis e mal formadas, com ruído de linha, comumente encontradas no código perl e sed (etc.), que são 'controversas' (lixo).
fonte
O melhor uso válido e normal para regex é a validação de formato de endereço de email.
Essa é uma boa aplicação disso.
Eu usei expressões regulares inúmeras vezes como únicas no TextPad para massagear arquivos simples, criar arquivos CSV, criar instruções de inserção SQL e esse tipo de coisa.
Expressões regulares bem escritas não devem ser muito lentas. Normalmente, as alternativas, como muitas chamadas para substituir, são opções muito mais lentas. Pode fazê-lo de uma só vez.
Muitas situações exigem expressões exatamente regulares e nada mais.
Substituir caracteres especiais não imprimíveis por caracteres inócuos é outro bom uso.
É claro que posso imaginar que existem algumas bases de código que usam demais expressões regulares em detrimento da capacidade de manutenção. Eu nunca vi isso sozinho. Na verdade, fui evitado pelos revisores de código por não usar expressões regulares o suficiente.
fonte