Por que as expressões regulares são tão controversas? [fechadas]

212

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?

Gumbo
fonte
9
se isso é uma discussão, não deveria ser fechado? mas vejo uma pergunta real lá, talvez a tag de discussão não pertença?
RCIX
6
Sem brincadeiras. Você fala disso e as pessoas começam a ficar loucas por aqui.
21919 Ryan Florence
1
Boa observação e redação na pergunta!
imz - Ivan Zakharyaschev 28/01
A pergunta é baseada em opiniões, a regra também deve ser aplicada aqui (ou a pergunta deve ser editada para direcionar uma resposta precisa). Dito isto, presumo que a controvérsia do regex vem da imprecisão dos tutoriais e manuais sobre o assunto. Na maioria das vezes, se não todas as informações são misturadas, além disso, não temos todas as características. Adicione a esse idioma que você não usa, você acaba aprendendo algo para perceber no futuro que isso pode significar outra coisa. E, finalmente, caracteres regex especiais não se limitam a um significado que adiciona mais confusão.
intika 21/01

Respostas:

136

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.

Kyle Cronin
fonte
2
E sim, as expressões regulares podem ser extremamente lentas se comparadas ao uso de funções simples. E não apenas lento, mas o desempenho do mecanismo regex pode ser totalmente imprevisível quando confrontado com entradas arbitrárias (fornecidas pelo usuário).
Pacerier 01/12/2015
1
Se você sabe como o regex funciona, não é um problema.
Shiplu Mokaddim
8
Pacerier @, não é padrões lentos , é motores lentos . A maioria dos mecanismos de expressão regular (modernos) não é adequada para padrões complexos (por exemplo, muitos |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 (em grep, 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.html
hagello
122

Tornando Regexes Mantíveis

Um grande avanço para desmistificar os padrões anteriormente referidos como "expressões regulares" é o /xsinalizador 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 $4ou \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:

$ dupword = qr {\ b (?: (\ w +) (?: \ s + \ g {-1}) +) \ b} xi;
$ citado = qr {(["']) $ dupword \ 1} x;

E aqui está um exemplo da abordagem superior das capturas nomeadas:

$dupword = qr{ \b (?: (?<word> \w+ ) (?: \s+ \k<word> )+ ) \b }xi;
$quoted  = qr{ (?<quote> ["'] ) $dupword  \g{quote} }x;

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ê:

… Certifique-se de nunca escrever padrões de ruído de linha. Você não precisa e não deveria. Não é possível manter nenhuma linguagem de programação que proíba espaços em branco, comentários, sub-rotinas ou identificadores alfanuméricos. Portanto, use todas essas coisas em seus padrões.

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;

$rfc5322 = qr{

   (?(DEFINE)

     (?<address>         (?&mailbox) | (?&group))
     (?<mailbox>         (?&name_addr) | (?&addr_spec))
     (?<name_addr>       (?&display_name)? (?&angle_addr))
     (?<angle_addr>      (?&CFWS)? < (?&addr_spec) > (?&CFWS)?)
     (?<group>           (?&display_name) : (?:(?&mailbox_list) | (?&CFWS))? ; (?&CFWS)?)
     (?<display_name>    (?&phrase))
     (?<mailbox_list>    (?&mailbox) (?: , (?&mailbox))*)

     (?<addr_spec>       (?&local_part) \@ (?&domain))
     (?<local_part>      (?&dot_atom) | (?&quoted_string))
     (?<domain>          (?&dot_atom) | (?&domain_literal))
     (?<domain_literal>  (?&CFWS)? \[ (?: (?&FWS)? (?&dcontent))* (?&FWS)?
                                   \] (?&CFWS)?)
     (?<dcontent>        (?&dtext) | (?&quoted_pair))
     (?<dtext>           (?&NO_WS_CTL) | [\x21-\x5a\x5e-\x7e])

     (?<atext>           (?&ALPHA) | (?&DIGIT) | [!#\$%&'*+-/=?^_`{|}~])
     (?<atom>            (?&CFWS)? (?&atext)+ (?&CFWS)?)
     (?<dot_atom>        (?&CFWS)? (?&dot_atom_text) (?&CFWS)?)
     (?<dot_atom_text>   (?&atext)+ (?: \. (?&atext)+)*)

     (?<text>            [\x01-\x09\x0b\x0c\x0e-\x7f])
     (?<quoted_pair>     \\ (?&text))

     (?<qtext>           (?&NO_WS_CTL) | [\x21\x23-\x5b\x5d-\x7e])
     (?<qcontent>        (?&qtext) | (?&quoted_pair))
     (?<quoted_string>   (?&CFWS)? (?&DQUOTE) (?:(?&FWS)? (?&qcontent))*
                          (?&FWS)? (?&DQUOTE) (?&CFWS)?)

     (?<word>            (?&atom) | (?&quoted_string))
     (?<phrase>          (?&word)+)

     # Folding white space
     (?<FWS>             (?: (?&WSP)* (?&CRLF))? (?&WSP)+)
     (?<ctext>           (?&NO_WS_CTL) | [\x21-\x27\x2a-\x5b\x5d-\x7e])
     (?<ccontent>        (?&ctext) | (?&quoted_pair) | (?&comment))
     (?<comment>         \( (?: (?&FWS)? (?&ccontent))* (?&FWS)? \) )
     (?<CFWS>            (?: (?&FWS)? (?&comment))*
                         (?: (?:(?&FWS)? (?&comment)) | (?&FWS)))

     # No whitespace control
     (?<NO_WS_CTL>       [\x01-\x08\x0b\x0c\x0e-\x1f\x7f])

     (?<ALPHA>           [A-Za-z])
     (?<DIGIT>           [0-9])
     (?<CRLF>            \x0d \x0a)
     (?<DQUOTE>          ")
     (?<WSP>             [\x20\x09])
   )

   (?&address)

}x;

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::Grammarsmó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:

#!/usr/bin/perl

use strict;
use warnings;
use 5.010;
use Data::Dumper "Dumper";

my $rfc5322 = do {
    use Regexp::Grammars;    # ...the magic is lexically scoped
    qr{

    # Keep the big stick handy, just in case...
    # <debug:on>

    # Match this...
    <address>

    # As defined by these...
    <token: address>         <mailbox> | <group>
    <token: mailbox>         <name_addr> | <addr_spec>
    <token: name_addr>       <display_name>? <angle_addr>
    <token: angle_addr>      <CFWS>? \< <addr_spec> \> <CFWS>?
    <token: group>           <display_name> : (?:<mailbox_list> | <CFWS>)? ; <CFWS>?
    <token: display_name>    <phrase>
    <token: mailbox_list>    <[mailbox]> ** (,)

    <token: addr_spec>       <local_part> \@ <domain>
    <token: local_part>      <dot_atom> | <quoted_string>
    <token: domain>          <dot_atom> | <domain_literal>
    <token: domain_literal>  <CFWS>? \[ (?: <FWS>? <[dcontent]>)* <FWS>?

    <token: dcontent>        <dtext> | <quoted_pair>
    <token: dtext>           <.NO_WS_CTL> | [\x21-\x5a\x5e-\x7e]

    <token: atext>           <.ALPHA> | <.DIGIT> | [!#\$%&'*+-/=?^_`{|}~]
    <token: atom>            <.CFWS>? <.atext>+ <.CFWS>?
    <token: dot_atom>        <.CFWS>? <.dot_atom_text> <.CFWS>?
    <token: dot_atom>        <.CFWS>? <.dot_atom_text> <.CFWS>?
    <token: dot_atom_text>   <.atext>+ (?: \. <.atext>+)*

    <token: text>            [\x01-\x09\x0b\x0c\x0e-\x7f]
    <token: quoted_pair>     \\ <.text>

    <token: qtext>           <.NO_WS_CTL> | [\x21\x23-\x5b\x5d-\x7e]
    <token: qcontent>        <.qtext> | <.quoted_pair>
    <token: quoted_string>   <.CFWS>? <.DQUOTE> (?:<.FWS>? <.qcontent>)*
                             <.FWS>? <.DQUOTE> <.CFWS>?

    <token: word>            <.atom> | <.quoted_string>
    <token: phrase>          <.word>+

    # Folding white space
    <token: FWS>             (?: <.WSP>* <.CRLF>)? <.WSP>+
    <token: ctext>           <.NO_WS_CTL> | [\x21-\x27\x2a-\x5b\x5d-\x7e]
    <token: ccontent>        <.ctext> | <.quoted_pair> | <.comment>
    <token: comment>         \( (?: <.FWS>? <.ccontent>)* <.FWS>? \)
    <token: CFWS>            (?: <.FWS>? <.comment>)*
                             (?: (?:<.FWS>? <.comment>) | <.FWS>)

    # No whitespace control
    <token: NO_WS_CTL>       [\x01-\x08\x0b\x0c\x0e-\x1f\x7f]

    <token: ALPHA>           [A-Za-z]
    <token: DIGIT>           [0-9]
    <token: CRLF>            \x0d \x0a
    <token: DQUOTE>          "
    <token: WSP>             [\x20\x09]

    }x;

};


while (my $input = <>) {
    if ($input =~ $rfc5322) {
        say Dumper \%/;       # ...the parse tree of any successful match
                              # appears in this punctuation variable
    }
}

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.

tchrist
fonte
9
SIM! SIM! Finalmente, alguém mostra um ótimo exemplo de quão regexes legíveis podem ser com o modificador x. Eu não posso acreditar como poucas pessoas sabem que ela existe, e muito menos usá-la.
Shabbyrobe
1
@Shabbyrobe: Não é só /x. É usar as expressões regulares gramaticalmente, com (?&name)sub-rotinas internas de expressões regulares, que realmente fazem isso brilhar.
tchrist
+1 Você sempre aprende algo novo. Eu não sabia que o PCRE tinha uma condição "falsa" para define.
NikiC
5
Da mesma forma, o Python tem uma re.VERBOSEbandeira.
Caracol mecânico
3
Basta ir em frente e dizer que ainda estou impressionado com o quanto as pessoas irão para tornar a regex utilizável.
Slater Victoroff
68

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.

Chas. Owens
fonte
4
Basta lembrar que a maioria dos analisadores -lexical analyzers- ainda usam expressões regulares para analisar as suas coisas :-)
Jasper Bekkers
62
Dizer que os analisadores usam expressões regulares é como dizer que os analisadores usam instruções de atribuição. Isso não significa nada até você ver como eles estão sendo usados.
Chas. Owens
24
Usar um RegEx quando um analisador é melhor é irritante. Usar um RegEx quando as funções de localização ou substituição da string padrão do idioma funcionarem (e geralmente em tempo linear) é imperdoável.
jmucchiello
1
Concordado, porque um RegEx tem que ser um macaco de todos os negócios que o processamento de sobrecarga é enorme. Só porque o uso de um mecanismo RegEx parece fácil, não significa que é uma solução melhor do que um analisador iterativo (limite dependente do desenvolvedor). Um dos meus exemplos favoritos do PHP split($pattern,$string)vs explode($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 eles
Rudu
4
Analisadores lexicais podem de fato usar expressões regulares. Eles também são conhecidos como tokenizadores, mas não são analisadores sintáticos (ou analisadores). Para ler uma string bastante complicada, um tokenizer deve ser usado para ler a string como tokens (talvez com expressões regulares, talvez não, dependendo do tokenizer). Esses tokens devem ser passados ​​para o analisador, que os processará com regras gramaticais, que definitivamente não são regexes.
Axel
53

Quase 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.

Barry Brown
fonte
11
Sim, nunca perdoei o Python por tornar a sintaxe do regex detalhada usando uma biblioteca. Eu acho que é pureza sobre sanidade.
slikts 01/09/10
7
Eu venho de um plano unix, usei cargas sed, awk e perl e, é claro, fiz bastante grepping, mas sei que quando eu uso um regex, é um hack somente de gravação que eu odeio manter. É bom para scripts de shell / temporizadores, mas para o trabalho real, para qualquer coisa que não seja apenas pegar alguns dados para salvar agora, agora uso um tokenizer / lexer / analisador adequado com sintaxe clara. Meu favorito faz tudo / qualquer, limpa + pode se auto-otimizar. Aprendi da maneira mais difícil, e ao longo de muitos anos, que um pouco de autodisciplina no início significa menos esforço depois. Um regex é um momento no teclado e uma vida inteira desaprovada.
AndrewC
44

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.

Bill Karwin
fonte
4
Existem excelentes ferramentas para fora lá para regexps depuração: regexbuddy.com
Jasper Bekkers
15
perl -Mre = debug -e "q [aabbcc] = ~ / ab * [cd] /"
Brad Gilbert
15
Acho que nunca consigo ver o acrônimo "FSM" sem pensar no Monstro do Espaguete Voador.
Shabbyrobe
4
@ Shabyrobe: Não quero ofender. Se desejar, você pode usar o autômato finito determinístico (DFA).
precisa
37

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.

Jasper Bekkers
fonte
2
Bem .. a diferença é que múltiplos espaços têm significado em regex, onde em outros idiomas que não o fazem e é por isso que eles são geralmente forros (que às vezes quebrar a várias linhas :)
Rado
14
@Rado: Perl, por exemplo, possui o xmodificador 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.
Nathan Fellman
9
Da mesma forma Python também re.Xconhecido como re.VERBOSE.
Craig McQueen
2
Da mesma forma, o xmodificador em tcl. Eu acredito que é bastante padrão, já que o tcl, ao contrário de outros idiomas, não usa o PCRE.
Sleevetman
2
@AndrewC Essa é uma das más interpretações mais grosseiras que este post poderia ter recebido.
Jasper Bekkers
28

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.

dkretz
fonte
3
Então você está usando o IDE errado ... Até meu editor de texto fornece dicas sobre expressões regulares.
CurtainDog
1
Em uma nota lateral, o Expresso e o The Regex Coach são ferramentas muito úteis para construir expressões regulares.
194/09 Mun
22
Como no mundo você completaria automaticamente uma expressão regular?
AmbroseChapel
3
O EditPad Pro possui destaque de sintaxe para expressões regulares na caixa de pesquisa, mas acho isso mais irritante do que útil e o mantenho desativado. Mas agradeço que me informe quando tenho colchetes incomparáveis; parênteses, em particular, pode ser um urso para acompanhar.
276 Alan Moore Alan
2
@ AmbroseChapel - Estou alguns anos atrasado para esta discussão. Mas eu criei um mecanismo de preenchimento automático em regexhero.net/tester. Ele é iniciado pelas construções comuns dentro de colchetes redondos (), quadrados []ou encaracolados {}. Também funcionará com a barra invertida.
21811 Steve
17

" 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.

Anthony
fonte
16

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.

allyourcode
fonte
2
A página pareceu mudar para docs.python.org/howto/regex
Dominic K
@DMan Obrigado. Vou editar minha resposta para refletir.
usar o seguinte código
11

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.

Peter Mortensen
fonte
7

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.

Svante
fonte
5

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.

Tanktalus
fonte
Claro que você pode analisar qualquer um desses formatos em uma única regex, esse é o poder das regexes, baby! Quer você queira ou não fazer isso, é uma questão totalmente diferente.
Jasper
4

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 ().

AmbroseChapel
fonte
4

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

  • o regexp não é eficiente, porque construir o primeiro não é óbvio
  • alguns programadores "esquecem" de compilar apenas uma vez que um regexp seja usado várias vezes (como um Padrão estático em Java)
  • alguns programadores optam pela estratégia de tentativa e erro - funciona ainda menos com regexps!
e2-e4
fonte
4

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 :))

Rajeev
fonte
2
Eu acho que é falso ignorar a maioria dos desenvolvedores ... como preguiçoso. Eu diria que a sintaxe é muito enigmática, não intuitiva e cheia de truques, para os não iniciados, o que leva a uma alta barreira à entrada. Pela mesma razão, Perl tem uma reputação "ruim" para muitos, mas também é uma linguagem muito poderosa. É como tentar ler expressões matemáticas antes de conhecer os símbolos. É assustador, e os desenvolvedores precisam ser judiciais com seu tempo para saber que obterão benefícios por aprender essa sintaxe.
Katastic Voyage
Você vai perder casos de ponta em HTML porque o HTML não é uma linguagem regular. Você está seguro se a sua intenção é analisar um subconjunto conhecido de HTML
Boyang
2

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.

Al Katawazi
fonte
2
Você está perdendo o ponto. A idéia das regexes é que você investe algum tempo em aprendê-las e, quando terminar, não precisará mais de uma aula mágica de "ler uma data". Em vez disso, é necessário muito pouco esforço regular para eles. Além disso, será necessário apenas um pequeno esforço para escrever um para "aaaa / mm / dd", como é necessário escrever um para "mm-dd-aaaa", ou mesmo um para "mm-aaaa / dd" (que ganhou acontece com frequência, mas é um exemplo de como você pode fazer coisas que uma aula mágica nunca pode ").
Jasper
1

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.

Brent Baisley
fonte
0

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.

ndr
fonte
como as implementações de regex diferem na abordagem da correspondência máxima, o que eu acho que você está chamando de "ganância"? Você quer dizer a diferença entre mais à esquerda mais longa em comparação com os mais longos-mais à esquerda semântica? Essa é a única diferença que eu conheço; isto é, se a ganância supera a ansiedade ou vice-versa .
tchrist
0

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.

Aif
fonte
0

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.

Satya Prakash
fonte
1
A leitura de expressões regulares é tarefa difícil somente quando o programador que as criou não conseguiu usar espaços em branco, comentários, identificadores alfanuméricos e talvez também sub-rotinas incorporadas via execução atrasada. Em resumo, todas as técnicas de engenharia de software aplicáveis ​​à programação geral também devem ser seguidas em expressões regulares. Se esses princípios forem ignorados, o escritor não estará produzindo código profissional.
Tcrist
Acho que seu gerente não sabe que "o verdadeiro herói da programação é quem escreve código negativo".
Rajeev
Se o seu gerente vai pedir que você realize o trabalho com três linhas de código (incluindo regexps), elogiando alguns colegas de trabalho idiotas que fizeram isso em 900 linhas do Assembler ... sugiro encontrar um novo emprego.
Phil Perry
0

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).

Sam Watkins
fonte
-4

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.

Chris Morley
fonte
10
A experiência mostra que as expressões regulares são na verdade uma ferramenta muito ruim para validação de formato de endereço de email. Um validador de formato verdadeiramente completo implementado como uma expressão regular é uma monstruosidade de centenas de caracteres, enquanto a maioria dos validadores "bons o suficiente" mais curtos que a maioria das pessoas leva 5 minutos para criar rejeitará grandes categorias de endereços entregáveis ​​válidos.
Dave Sherohman
Eu ouço você cara. Eu estava falando sobre o "bom o suficiente" e, embora as faixas grandes possam ser grandes em teoria, considere a porcentagem de cobertura que você obtém em uma expressão tão curta. Eu também vi a monstruosidade, mas qual é a sua alternativa elegante?
19420 Chris Morley
2
Eu usei algo como \ w @ \ w +. \ W + para encontrar rapidamente o endereço de email em um grande diretório de arquivos onde a velocidade era importante e alguns falsos positivos ou negativos não eram importantes. Mas a melhor maneira de validar um endereço de email parece ser enviar um email para ele.
RossFabricant 03/09/09
Sim e-mail a especificação de endereço é uma confusão desagradável stackoverflow.com/questions/611775/...
Nick Van Brunt
@ Nick, @ Dave: A validação do endereço de email não precisa ser uma bagunça desagradável.
tchrist 01/12/10