Eu adoro expressões regulares. Não, não sei se o senhor entendeu: Eu realmente amor expressões regulares.
O senhor pode achar um pouco estranho que um hacker que cresceu usando uma linguagem com a palavra-chave ain’t se apaixonaria tanto por algo tão obtuso e arcano como as expressões regulares. Não tenho certeza de como isso funciona. Mas funciona. Expressões regulares são o máximoElas devem ser uma parte essencial do kit de ferramentas de todo programador moderno.
Se o senhor já conversou sobre expressões regulares com outro programador, invariavelmente já ouviu essa frase de 1997:
Algumas pessoas, quando confrontadas com um problema, pensam: “Já sei, vou usar expressões regulares”. Agora elas têm dois problemas.
A citação é de Jamie Zawinski, um hacker de classe mundial que admiro muito. Se ele está nos dizendo para não usar expressões regulares, será que devemos nos preocupar? Talvez, se o senhor vive e morre por frases de efeito. Mas a história é um pouco mais complexa do que isso, conforme evidenciado pelo senhor. a pesquisa exaustiva de Jeffrey Friedl sobre a citação de Zawinski. O próprio Zawinski comentou sobre o assunto. Analisando o texto completo das postagens de Jamie no tópico original de 1997, encontramos o seguinte:
A natureza do Perl incentiva o uso de expressões regulares quase que excluindo todas as outras técnicas; elas são, de longe, a maneira mais “óbvia” (pelo menos, para pessoas que não conhecem melhor) de ir do ponto A ao ponto B.
A primeira citação é muito superficial para ser levada a sério. Mas concordo plenamente com a segunda. Este é o ponto que Jamie estava tentando mostrar: não que as expressões regulares sejam ruins, por si só, mas que o uso excessivo de expressões regulares é ruim.
Não poderia estar mais de acordo. As expressões regulares são como um molho picante particularmente apimentado – devem ser usadas com moderação e com moderação somente quando apropriado. O senhor deve tentar resolver todos os problemas que encontrar com uma expressão regular? Bem, não. Nesse caso, o senhor estaria escrevendo Perle não sei se o senhor precisa desse tipo de dor de cabeça. Se o senhor encharcar seu prato com molho picante, vai se arrepender muito, muito mais tarde.
Da mesma forma que não consigo imaginar a comida sem uma pitada de molho picante de vez em quando, não consigo imaginar a programação sem uma expressão regular ocasional. Seria uma experiência insípida e insatisfatória.
Mas espere! Deixe-me adivinhar! A última vez que o senhor teve que ler uma expressão regular e decifrá-la, sua cabeça quase explodiu! Ora, não era nem mesmo código; era apenas um monte de palavras ininteligíveis Q*Bert ininteligível!
Acalme-se. Respire fundo. Relaxe.
Deixe-me ser bem claro neste ponto: se o senhor ler uma expressão regular incrivelmente complexa e impossível de ser decifrada em sua base de código, eles fizeram isso errado. Se o senhor escrever expressões regulares que sejam difíceis de ler em sua base de código, o senhor está fazendo isso errado.
Veja. Escrever para que as pessoas possam entendê-lo é difícil. Não me importa se é código, inglês, expressões regulares ou klingon. Seja o que for, posso mostrar ao senhor um exemplo de alguém que escreveu algo que é praticamente indistinguível da linguagem sem sentido. Também posso mostrar ao senhor algo escrito no mesmo meio que é tão bonito que fará seus olhos lacrimejarem. Portanto, o argumento de que as expressões regulares são, de alguma forma, fundamentalmente impossíveis de serem escritas ou lidas, para mim, não tem fundamento. Como tudo o mais, é preciso apenas um pouco de habilidade.
Coragem, soldado. Até mesmo o código Ruby é difícil de ler até que o senhor aprenda os símbolos e as palavras-chave que compõem a linguagem. Se puder aprender a ler código em qualquer linguagem de sua escolha, o senhor poderá absolutamente pode ler algumas expressões regulares. Simplesmente não é tão difícil. Não vou aborrecê-lo com uma explicação completa da dezena de elementos básicos das expressões regulares; Mike já cobriu esse assunto melhor do que eu:
Gostaria de ilustrar com um exemplo real, uma expressão regular que escrevi recentemente para remover HTML perigoso da entrada. Ela foi extraída do A rotina SanitizeHtml Publiquei no RefactorMyCode.
var whitelist = @"</?p>|<brs?/?>|</?b>|</?strong>|</?i>|</?em>| </?s>|</?strike>|</?blockquote>|</?sub>|</?super>| </?h(1|2|3)>|</?pre>|<hrs?/?>|</?code>|</?ul>| </?ol>|</?li>|</a>|<a[^>]+>|<img[^>]+/?>";
O que o senhor vê aqui? A lista branca de nomes de variáveis é uma forte dica. Uma coisa de que gosto nas expressões regulares é que elas geralmente se parecem com o que estão combinando. O senhor vê uma lista de tags HTML, certo? Talvez com e sem suas tags de fechamento?
Sinceramente, isso é tão difícil de entender? Para mim, é perfeitamente legível. Mas podemos fazer melhor. Na maioria dos dialetos de regex modernos, o senhor pode ativar um modo em que os espaços em branco não são mais significativos. Isso libera o senhor para usar espaços em branco e comentários em sua expressão regular, assim.
var whitelist = @"</?p>| <brs?/?>| (?# allow space at end) </?b>| </?strong>| </?i>| </?em>| </?s>| </?strike>| </?blockquote>| </?sub>| </?super>| </?h(1|2|3)>| (?# h1,h2,h3) </?pre>| <hrs?/?>| (?# allow space at end) </?code>| </?ul>| </?ol>| </?li>| </a>| <a[^>]+>| (?# allow attribs) <img[^>]+/?> (?# allow attribs) ";
O senhor entende agora? Tudo o que fiz foi adicionar alguns comentários e muitos espaços em branco. A mesma técnica exata que eu usaria em qualquer código, na verdade.
Mas como criei essa expressão regular? Como sei que ela faz o que eu acho que faz? Como faço para testá-la? Bem, novamente, faço isso da mesma forma que faço com todos os meus outros códigos: Uso uma ferramenta. Minha ferramenta preferida é o RegexBuddy.
Agora temos realce de sintaxe e, o que é mais importante, exibição em tempo real das partidas na parte inferior de nossos dados de teste enquanto digitamos. Isso é muito importante. Se o senhor estiver se perguntando por que seu IDE não faz isso automaticamente com todas as cadeias de caracteres regex que detecta em seu código, diga-me. Há anos que me pergunto a mesma coisa.
Na minha opinião, o RegexBuddy é, de longe, a melhor ferramenta de regex do mercado. Nada mais chega perto. Mas ela custa dinheiro. Se o o senhor não usa software que custa dinheiro, há muitos alternativas por aí. O senhor não leria ou escreveria código no bloco de notas, certo? Então, por que o senhor tentaria ler ou escrever expressões regulares dessa forma? Antes que o senhor reclame da dificuldade de lidar com expressões regulares, o senhor precisa ter as ferramentas certas!
Esse trabalho vale a pena, pois as expressões regulares são incrivelmente poderosas e sucintas. Quão poderosas? Consegui escrever um higienizador de HTML de propósito especial e sem sentido com cerca de 25 linhas de código e quatro expressões regulares. Compare isso com um higienizador de HTML de uso geral que exigiria centenas, se não milhares de linhas de código procedural para fazer a mesma coisa.
No entanto, tenho algumas dicas para manter a sanidade mental ao lidar com expressões regulares:
- Faça não tentar fazer tudo em uma única uber-regex. Eu sei que o senhor pode fazer isso dessa forma, mas o senhor não vai fazer. Não vale a pena. Divida a operação em várias expressões regulares menores e mais compreensíveis e aplique cada uma delas. Ninguém conseguirá entender ou depurar essa regex monstruosa de 20 linhas, mas talvez tenham uma chance de entender e depurar cinco mini regexes.
- Use espaços em branco e comentários. Não estamos mais em 1997. Um regex minúsculo e ultracondensado não é mais uma virtude. Acionar o
IgnorePatternWhitespace
e use esse espaço em branco para tornar sua regex mais fácil de ser analisada e compreendida por nós, seres humanos. Comente livremente. - Obtenha uma ferramenta de expressão regular. Eu não fico olhando para as expressões regulares e tentando descobrir seu significado por pura força de vontade. O senhor também não deveria. É uma perda de tempo. Eu as colo na ferramenta de regex de minha preferência, RegexBuddyque não só me diz o que a expressão regular faz, mas também me permite percorrê-la e executá-la em alguns dados de teste. Tudo isso em tempo real, enquanto digito.
- Expressões regulares não são analisadores. Embora o senhor possa fazer algumas coisas incríveis com expressões regulares, elas são fracas na correspondência equilibrada de tags. Algumas variantes de regex têm correspondência balanceada, mas isso é claramente um hack – e um hack desagradável. Muitas vezes, o senhor pode fazer com que ela funcione mais ou menos, como fiz na rotina sanitize. Mas, por mais inteligente que seja seu regex, não se iluda: ele não substitui, de forma alguma, um analisador real.
Se o senhor tem medo de expressões regulares, não tenha. Comece aos poucos. Usadas de forma responsável e com as ferramentas certas, elas são grandes, poderosas – ouso dizer, picante – ganha. Se as expressões regulares fizerem parte de seu conjunto de ferramentas, o senhor poderá escrever menos código que faz mais. Ele simplesmente… terá um sabor de massa.
Na verdade, o senhor poderá gostar tanto delas que se esquecerá completamente do “segundo problema”.