Por que as expressões regulares são tão morbidamente atraentes?

23

Anexo 1 , Anexo 2 , acho que você não achará difícil lembrar de outros exemplos.

O problema é que, se houver mais de uma maneira de resolver um problema, o programador PHP (eu costumo navegar na tag PHP no StackOverflow) solicitará ajuda na solução que envolve expressões regulares.

Mesmo quando será menos econômico, mesmo quando o manual do php sugere ( link ) o uso em str_replacevez de any preg_*ou ereg_*function quando nenhuma regra de substituição sofisticada é necessária.

Alguém tem alguma idéia de por que isso acontece?

Não me interpretem mal, alguns dos meus melhores amigos são expressões regulares e eu não desprezo o Perl. O que não entendo é por que não há nenhuma alternativa, mesmo quando o exagero é óbvio (regex para alternar cadeias) ou a complexidade do código aumenta exponencialmente (regex para obter dados de html em PHP )

cbrandolino
fonte
2
Você pode citar o que o manual do php realmente diz.
ChrisF
1
Por serem enigmáticos, você quer fazer parte do exclusivo clube kewl kidz? E principalmente porque eles fornecem uma maneira curta de expressar uma correspondência ou extração, e é para isso que eles são feitos. Certamente, para casos fictícios, a análise personalizada, se melhor, mas o tempo de desenvolvimento ao escrever uma regex rápida é a favor da regex.
haylem
Você enfatizou a parte errada da última frase: A parte ultrajante é "do html", não "no PHP".
Izkata # 03

Respostas:

20

Por que as expressões regulares são tão morbidamente atraentes?

Porque, no nível subconsciente, eles se sentem como um programa inteligente inteiro, que pode realizar muito por conta própria, enquanto é abrangente e se auto-ajusta (padrões de pensamento).

É por isso que as pessoas acreditam imediatamente que expressões regulares resolverão qualquer uma de suas tarefas baseadas em texto, de alguma forma não achando que pode ser um exagero e nem percebendo que isso pode me exagerar (analisando idiomas com ele).

Uma coisa minúscula que contém poder mágico. Você não pode dizer não, pode?

user8685
fonte
5
+1 - Uma pequena coisa enigmática , nada menos.
AJ Johnson
Hobitses são tricksty
Ben DeMott
49

Quando a única ferramenta que você possui é uma regex, todo problema parece ^((?>[a-zA-Z\d!#$%&'*+\-/=?^_{|}~]+\x20*|"((?=[\x01-\x7f])[^"\\]|\\[\x01-\x7f])*"\x20*)*(?<angle><))?((?!\.)(?>\.?[a-zA-Z\d!#$%&'*+\-/=?^_{|}~]+)+|"((?=[\x01-\x7f])[^"\\]|\\[\x01-\x7f])*")@(((?!-)[a-zA-Z\d\-]+(?<!-)\.)+[a-zA-Z]{2,}|\[(((?(?<!\[)\.)(25[0-5]|2[0-4]\d|[01]?\d?\d)){4}|[a-zA-Z\d\-]*[a-zA-Z\d]:((?=[\x01-\x7f])[^\\\[\]]|\\[\x01-\x7f])+)\])(?(angle)>)$

glenatron
fonte
16
A tentação de escolher essa resposta é muito forte, mas acho que devo resistir, já que é minha primeira pergunta aberta aqui e tenho que fingir seriedade por um tempo.
Cbrandolino
1
@ Dev, faz muito sentido. Meu comentário foi apenas uma maneira supostamente engraçada de expressar minha gratidão pela resposta.
Cbrandolino
17
O que diabos isso combina?
Tom O'Connor
4
Eu não sei ... Eu acho que isso resume tudo. Se você conhece regex e não conhece os outros métodos, por que procuraria? Você já possui uma ferramenta que, se feita corretamente, cuidará do trabalho. Até que eles se deparem com o método mais simples ou sejam informados sobre isso, o regex será o método abrangente, mesmo que seja mais complexo do que o necessário.
Aeo
4
@ Tom O'Connor Acho que é algo parecido com o Regex por combinar um endereço de e-mail da RFC 2822, mas eu tive que escolher alguns caracteres porque eles estavam causando estragos com a redução.
glenatron
23

Eu acho que é porque:

  1. Eles são fantasticamente concisos (quando usados ​​corretamente) em comparação com o código equivalente e
  2. Eles são amplamente suportados em linguagens de programação, portanto, a maioria dos desenvolvedores está familiarizada com eles.
hallidave
fonte
3
# 2 faz sentido.
Cbrandolino
23

Nas fases anteriores da minha carreira (ou seja, pré-PHP), eu era um guru do Perl, e um aspecto importante do gurudom do Perl é o domínio das expressões regulares.

Na minha equipe atual, sou literalmente o único de nós que alcança regex antes de outras ferramentas (geralmente mais desagradáveis). Parece que para o resto da equipe eles são pura mágica. Eles vão até a minha mesa e pedem um regex que me leva literalmente dez segundos para serem montados, e depois ficam encantados quando funciona. Eu não sei - eu trabalhei com eles por tanto tempo, é natural neste momento.

Na ausência de fluência regular, você fica com combinações de instruções de controle de fluxo envolvendo as instruções strstr e strpos, que ficam feias e difíceis de executar em sua cabeça. Prefiro criar um regex elegante do que trinta linhas de busca por cordas.

Dan Ray
fonte
2
Não posso aprovar isso o suficiente.
CaffGeek
8
Estou curioso: você regexp's tão fluentemente quanto escreve?
Peterchen
7
Espero que você esteja realizando sessões regulares de treinamento em regex e / ou documentando o inferno do seu código; caso contrário, você estará criando um pesadelo de suporte para seus colegas de trabalho. O tempo que você economizou escrevendo esse regex pode ser perdido centenas de vezes pelas pessoas que tentam entender o que esse "regex elegante" está fazendo.
Jeff Knecht
3
Tão bom. Você pode ouvir o cabo de guerra entre as expressões de amor e ódio aqui mesmo nesses comentários.
Dan Ray
1
@ Ben Lee: Eu acho que sim - OTOH, eu nunca encontrei um regex comentado na natureza. Alguns dos problemas com expressões regulares podem ser baseados em uma atitude de frescor.
Peterchen
16

Pelo contrário. As pessoas papagaiam o regex são memes malvados com muita frequência IMO. É óbvio que preg_match é usado em excesso php, mas é menos óbvio que muitas vezes é sensato fazê-lo (em PHP).

Eu iria tão longe e conjecturaria que é mais uma micro-otimização no php land para usar as funções de string. Existem muitos e muitos úteis, e geralmente são a melhor escolha. Mas você não deve evitar a preg_matchfavor de múltiplos strpose ifcorrentes. Porque, na prática, o libpcre é geralmente mais rápido do que o PHP pode executar um loop procurando alternativas de strings, por exemplo

Como um exemplo recente me fez perceber, testando se uma string é toda em minúscula:

 if ($string == strtolower($string))

É mais legível que:

 if (!preg_match("/[A-Z]/", $string))

E você assumiria que o primeiro deve ser mais rápido, já que é totalmente PHP. Mas, na realidade, o regex somente examina a string uma vez e pode abortar a condição negada assim que encontrar uma letra maiúscula. A abordagem strtolower (), no entanto, examina a string duas vezes. O primeiro strtolower () cria uma duplicata de sequência iterando sobre cada letra, comparando-a e colocando-a em maiúscula. Em seguida, ==itera o original e a cópia novamente, comparando-os mais uma vez.

Portanto, esse não é um caso óbvio. E para ser objetivo, o primeiro é geralmente mais rápido, já que você normalmente compara seqüências curtas. Mas é imperativo não ficar cego com a suposição de que as funções de string do PHP são sempre aconselháveis ​​sobre expressões regulares.

(Estou tentado a acrescentar outro comentário divertido sobre a resposta divertida de @ bobince em relação a xhtml-regexes, e como ela é frequentemente vinculada de uma maneira muito inútil. E as respostas mais objetivas abaixo são ignoradas.)

mario
fonte
1
Eu concordo com o seu exemplo; ainda assim, nesse caso em particular, eu preferiria 'strtolower ()' de qualquer maneira: no código não crítico, mesmo uma otimização de tempo de execução tão grande (em relação à outra implementação) é insignificante - a menos que você queira avaliar as letras minúsculas um enorme arquivo de texto, mas não consigo imaginar um caso em que isso seria útil.
Cbrandolino
1
@ cbrandolino: Nenhuma discussão lá. Esse material deve ser relevante e avaliado apenas para loops aninhados, onde pode fazer uma diferença factual.
mario
4
+1 Pelo fato de as pessoas sempre as atacarem, muito mais do que elas são suportadas.
Orbling
1
Como um dos "bashers do regexp": é divertido ver uma linha falar mais ou menos expressar para que sequência "manual" é necessário analisar 30 linhas de nedds. No entanto, a manutenção sofre nos exemplos mais realistas. Além disso, ao tentar aplicá-las a entradas não validadas, gerar diagnósticos adequados para entradas rejeitadas requer acrobacias adicionais. Para mim, é o código prototípico "somente gravação" - legal para scripts rápidos, uma porcaria para aplicativos de longa duração.
Peterchen
1
Qualquer um que não esteja escrevendo todas as suas expressões regulares no /xmodo de permitir espaço em branco para o cotovelo do fragmento cognitivo e de comentários para explicar por que as coisas estão sendo feitas, deve, obviamente, ter os ouvidos fechados. Porém, para expressões reais de complexidade razoável, considere aplicar o design de cima para baixo por meio de expressões gramaticais . Depois de ver a luz, você nunca mais voltará /@#$^^@#$^&&*)@#/.
tchrist
8

Expressões regulares são muito atraentes porque são a melhor ferramenta para analisar um idioma regular.

Eles têm as seguintes vantagens:

  • Eles são concisos . Geralmente, é necessário muito mais código para analisar uma linguagem regular específica usando um algoritmo específico que você criou do que com um regexp.
  • Eles são rápidos de usar. Geralmente, leva muito mais tempo para escrever um analisador para uma linguagem regular específica usando um algoritmo específico que você criou do que com um regexp.
  • Eles são fáceis . Depois de aprender o conjunto de caracteres especiais e seus significados, é fácil compor uma regexp (embora um pouco mais difícil de lê-los). Regexps são as próprias línguas - uma característica útil porque nossa espécie evoluiu para ser muito boa na linguagem.
  • Eles são rápidos . Uma vez compilados, eles podem corresponder a um comprimento de string Nno tempo O ( N).
  • Eles são flexíveis . Eles podem corresponder a qualquer idioma comum e muitos dados são expressos como um idioma comum.
  • Eles são onipresentes . A maioria das linguagens de programação possui suporte básico a regexp - por meio de bibliotecas externas ou incorporadas à própria linguagem. Também não há muita variação entre os próprios idiomas regexp.

Isso os torna atraentes para situações às quais são adequados, mas as pessoas podem usá-los em contextos em que não são a melhor ferramenta, porque:

  • Não entenda que o que eles correspondem não pode ser expresso usando uma expressão regular (por exemplo, HTML).
  • São preguiçosos (de uma maneira ruim) - conhecem uma ferramenta e reconhecem que não é a melhor ferramenta para o que estão fazendo, mas funcionará sem problemas 95% das vezes e gasta 95% do esforço de aprender um determinado idioma. analisador ou escrevendo um do zero.
  • Eles não sabem que existem melhores ferramentas.
david4dev
fonte
Er, eu estava me referindo a alguns casos particulares em que eles evidentemente não são a melhor maneira de proceder, mas ainda são usados. Gosto de regex (quero dizer, acho-os chatos e sem vida, mas ainda são muito úteis em alguns contextos) e sei quais são suas vantagens.
Cbrandolino
Concordo com o resto, mas rápido e fácil? A curva de aprendizado é íngreme: para um iniciante, é difícil descobrir por que uma expressão não funciona, e toda implementação de expressão regular parece ter pelo menos diferenças sutis; portanto, é preciso observar de onde você tenta aprender.
Peterchen 21/12
Por que todo mundo confunde extrair pequenos pedaços de HTML com a análise completa de uma página da Web completa em uma árvore de análise completa? É realmente estúpido. Acredite, quando edito páginas HTML vi, você aposta a sua vida :%s/foo/bar/gc. Se é bom o suficiente para um editor, é bom o suficiente para um script.
precisa saber é o seguinte
6

Hmmm, só posso adivinhar. Talvez algumas pessoas tenham experimentado que 30 linhas de seu código foram substituídas por uma regex de 20 caracteres, portanto, parece errado que elas usem qualquer outra coisa quando as regexes puderem ser usadas.

usuário281377
fonte
4

Isso se encaixa na maneira como algumas pessoas pensam. Não gosto deles, mas tenho amigos que parecem pensar em regexps. Eu acho que o padrão correspondente a parte do cérebro deles é mais exposto do que o da lógica formal. :-)

Lennart Regebro
fonte
6
Em termos de nossa história evolucionária, essa é a razão. Estávamos combinando padrões muito antes de definir gramáticas ou descobrir silogismos.
glenatron
1
Eu discordo, a programação envolve lógica e correspondência de padrões, duas áreas. Os regexps são muito bons na correspondência de padrões e devem ser usados ​​para essas tarefas. Diga também "eu não gosto deles", é jogar fora uma boa ferramenta para um trabalho específico.
Orbling
@Orbling: A questão não é se eles são bons ou ruins, mas por que algumas pessoas os usam demais e outros não.
Lennart Regebro
A pergunta pode ser, mas sua resposta sugere que um ou outro tipo de mente está em jogo, em vez de ambos.
Orbling
Eu não acho que "sugerir" é a palavra correta.
Lennart Regebro
3

Eu acho que a onipresença de regex é devido à onipresença de strings. A string é a estrutura de dados mais simples, a primeira que a maioria de nós aprende. Como todo o nosso código é escrito em forma simbólica, é natural que um programador considere modelar algo em forma simbólica. Mas se nossa linguagem de programação oferece alguma resistência quando tentamos estender sua sintaxe para nossas novas formas simbólicas inteligentes, todas elas terminam entre aspas. O modelo de dados relacionais possui SQL. O modelo de dados XML possui XQuery. Mas e o humilde modelo de dados de string? Regex!

Ontem mesmo, eu estava procurando na API uma nova estrutura Javascript brilhante que suporta o desenvolvimento de jogos HTML5. Ele possui um mecanismo declarativo para descrever os principais subsistemas necessários ao seu jogo. Como alguém especifica esses recursos? JSON? Notação de ponto fluente? Uma matriz? Não - uma sequência que contém uma lista de nomes de recursos separados por vírgula e espaço em branco. Gostaria de saber como ele analisa essa lista ...?

WReach
fonte
2

Porque você pode ver a coisa toda de uma só vez. Ao ver a coisa toda, pode ser mais fácil trabalhar com isso, e isso é sempre bom. É mais ou menos a razão pela qual muitos programadores de C ++ ainda usam instruções do tipo printf: não é seguro (embora o gcc possa pelo menos verificar os tipos nas instruções printf) e não é bonito, mas é compacto e utilizável.

Se é um regex bastante simples, eles geralmente são a melhor maneira de fazer as coisas - sua forma compacta e muitos recursos os tornam perfeitos para determinadas tarefas. O problema surge quando você torna o regex tão complicado que não consegue mais lê-lo ou quando usa um regex complexo para fazer algo que poderia ser feito mais rapidamente por meio de operações simples de string.

O Regex, como qualquer outra ferramenta poderosa, deve ser usado com moderação adequada - nem muito, nem muito pouco. E, a menos que o desempenho seja uma grande preocupação, um único regex às vezes pode ser mais rápido de gravar e mais fácil de depurar do que uma série de operações de string.

Michael Kohne
fonte
2

Hmm, as respostas atuais se concentram demais em aspectos técnicos e na legibilidade prós / contras (que é um ponto importante). Então, deixe-me tentar mudar um pouco mais para o ambiente / comunidade PHP:

  • PHP é a pequena meia-irmã de Perls . E parte integrante do Perl são expressões regulares (eles inventaram essas coisas, não foram?). Portanto, é uma das razões pelas quais os regexps também são difundidos no PHP.
  • O caso de uso do PHP coincidentemente não é muito diferente do caso de uso para expressões regulares. O PHP é estruturalmente usado para colar páginas HTML. E regexps funcionam em texto. (o que a WReach disse)
  • Micro otimização . Como mencionado anteriormente: as pessoas usam regexps e / ou funções de string PHP frequentemente após a velocidade percebida. Um problema central nos círculos PHP, não específico para regexps.
  • Expressões regulares são internas . Em Python, em Java, em C #, em Ruby? existe disponibilidade, mas um impedimento ao carregar um módulo extra. E veja como, em PHP ou Javascript, onde é um recurso principal, o padrão de uso é diferente. Outra exposição: CSS, onde está sendo usado com mais frequência.
  • O manual do PHP está com falha. Muitas vezes é. Expressões regulares são facilmente detectáveis, e adiei esse fato divertido porque é chato em sua obviedade: todos os malditos tutoriais e livros de introdução ao PHP sempre ensinam sobre expressões regulares, mas deixam de educar sobre casos de uso.
  • A API de string no PHP foi projetada pelas mesmas pessoas que trouxeram citações mágicas e o namespace \ separator. É abrangente, melhor que Java, mas não é glamouroso por inteiro. Particularmente, se as strings puderem dobrar como objetos (consulte Python), as funções de string poderão superar os regexps.

Mas isso apenas como notas laterais. Acredito que, de qualquer maneira, são principalmente razões de percepção e técnicas que levam ao uso excessivo e / ou ao desvio de expressões regulares em geral. No entanto, o PHP e sua base de usuários têm algumas propriedades que o compõem, e por que vemos mais perguntas sobre o SO a respeito [citação necessário!] E elas são "morbidamente atraentes" lá.

mario
fonte
1

Gosto de expressões regulares em geral, acho mais fáceis de ler / entender do que as 20 linhas de código que eu teria que substituí-las. Expressões regulares curtas são lidas e entendidas rapidamente e são relativamente fáceis de manter (se a expressão for alterada, você só terá uma linha para alterar em comparação com as 20 linhas de código para fazer a alteração). Há momentos em que são mal utilizados, mas muitas outras coisas.

A razão pela qual você provavelmente vê tanto abuso deles é porque você está navegando na seção PHP do StackOverFlow, como tenho certeza de que você sabe que existem muitos programadores imaturos de PHP por aí.

stoj
fonte
1

Por que as expressões regulares são tão morbidamente atraentes?

Eles não são. Eles são realmente feios pra caramba. E incompreensível. Eles são uma abominação que deve ser morta o mais rápido possível.

Agora, dito isso, voltarei à depuração de um pequeno aplicativo Perl. Não posso evitar; infelizmente, ainda são a melhor ferramenta para o trabalho.

2 rotações
fonte
4
Eu gosto de dizer que as expressões regulares não são nem "regular" ou "expressiva"
Andrew Barber
2
Eles são feios e incompreensíveis se você não os entende. Quando você alcança o zen do regex, eles são realmente muito elegantes.
Dan Ray
1
-1 Por decidir que todos os programadores gostam de ser obscuros e depois não considerar nenhuma outra explicação possível. ... Declarar por que você acha que é feio ou incompreensível teria ajudado.
Macneil
1
@ Macneil - Por favor, (embora sim, meus pensamentos estão nessa linha), a menos que você esteja me citando, não indique que eu disse / decidi algo que não fiz (a primeira parte do seu comentário). Quanto à sua pergunta, você as acha lindas ?! ... Eu não. E como esse é um site subjetivo, e essa é uma opinião subjetiva, não preciso nem desejo elaborar sobre ele. Nem vou tentar, por falar nisso.
Rook
1
@Rook - Eu acho que a maioria das pessoas olha para uma expressão regular complexa, decide que todas as expressões regulares são feias e depois para de pensar. O fato é que eles são uma ferramenta muito elegante e expressiva, se você pode definir seu preconceito sobre eles. Por sua própria lógica, muitos programadores não podem fazer álgebra, então a álgebra é provavelmente inerentemente má e deve ser abolida, pois claramente não é muito compreensível.
Dan Ray
0

O homem é uma criatura que usa ferramentas, e expressões regulares são ferramentas poderosas. Uma boa metáfora para expressões regulares é um cortador de carne de uma lanchonete. Se você quiser fatias finas de peru, carne enlatada, etc., é exatamente isso. No entanto, você precisa de mãos habilidosas para usá-lo, porque pode se cortar muito com ele e não sentirá nada até ver o sangue. O que quero dizer com isso é que o grande problema das expressões regulares é reduzi-las um pouco, significa que você corresponde a algo que não deveria, ou vice-versa, e não descobre até que isso cause um problema mais adiante no processo.

Larry Coleman
fonte
0

Expressões regulares são muito atraentes porque exercem poder. Você pode fazer um trabalho muito complicado em muito poucos caracteres.

O problema é que a construção de expressão regular padrão não é completa em Turing, o que significa que existem programas que você simplesmente não pode implementar com uma expressão regular, e as pessoas NÃO SABEM isso quando são atraídas pelo aparente poder das expressões regulares.

Acho que esse é o motivo da citação jwz de "agora eles têm dois problemas".

Eu acho que as expressões regulares do Perl são completas de Turing, mas, aparentemente, ainda não foi provado ou refutado de forma decisiva.

user1249
fonte
0

Porque é uma maneira eficiente de programar uma máquina de estados finitos, que é uma ferramenta poderosa quando aplicada. É basicamente sua própria linguagem para programar FSMs, o que é útil se você conhece a linguagem e irritante se não conhece.

DanTilkin
fonte
0

Na minha experiência, as expressões regulares são como uma arte antiga, algo obscuro, algumas pessoas se ressentem porque não conseguem entender a feitiçaria envolvida e talvez porque ninguém as explique para você. Não ouvi falar de universidades ensinando-as por algo menos trivial do que combinar um e-mail. Depois, há o funcionamento interno místico, já que a maioria das pessoas não os entende, eles devem ser lentos . E fazê-los funcionar bem na primeira tentativa é sempre um desafio para os novatos.

O mesmo pode ser dito sobre Perl, awk, Linux e tudo o que não possui botões brilhantes ou sintaxe colorida agradável. Então, é como adicionar complexidade às "tarefas triviais", basta dar alguns loops, divisões, um interruptor, alguma mágica e é isso, algo que pode funcionar. Mas bem, se você estiver do outro lado da estrada, as expressões regulares são belos cortadores de biscoitos que parecem ruído de sinal sem loops desagradáveis ​​ou mais coisas para depurar. Também gosto deles pela flexibilidade que oferecem. Quando o padrão para corresponder muda, basta alterar o regex, não o algoritmo ou a ferramenta / o que quer que seja, e é bom e está funcionando novamente. E como são uma sequência mágica, você pode colocá-la fora do código-fonte, se desejar. E outra coisa que me faz pensar em perl: se você escreve um regex com mais de 20 caracteres, parece que você realizou muito, pelo menos para mim, é tão elegante e compacto. Também sou um programador preguiçoso, não gosto de escrever muito código com boa identificação e comentários e adicionar alguns bugs à mistura.

alfa64
fonte