Regex é um saco pra você?

Uma tremenda dor de cabeça. :wink:

é bom pra quebrar a cabeça…

Há certas coisas que podem ser resolvidas com expressões regulares muito complicadas, ou então tentando efetuar a conversão e vendo se dá um erro. Experimente achar uma expressão regular que diga se um número “double” foi formatado corretamente em notação científica:

-123.456E+234

(a expressão regular seria “[-+]?[0-9]*.?[0-9]+([eE][-+]?[0-9]+)?” )

e veja se não é mais fácil simplesmente tentar converter o número (parseDouble) e capturar a NumberFormatException.

Outra é pegar um IP (que vai de 0.0.0.0 a 255.255.255.255, no caso do IPv4). A expressão seria:

\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b

mas obviamente é mais fácil tentar converter para um IP (java.net.IPAddress) e ver se a conversão deu certo ou não.

Veja o exemplo em http://www.regular-expressions.info/examples.html .

[quote=s4nchez][quote=victorwss]
Existem alguns casos estranhos que dificilmente são pegos em testes unitários feitos por meros mortais, como oO caso que o thingol deu, de que \d{3} também pega números chineses por exemplo. Dificilmente algum mero mortal pensaria nisso. Desta forma acabaria fazendo testes com coisas como “12”, “123”, “999”, “aaa”, “99a”, “a66”, “1234”, “123a” e coisas assim, e todos os testes teriam o resultado esperado. Mas, a regex ainda estaria incorreta mesmo assim, pois o certo seria [0-9]{3}. Se o cara for um guru de regex e se lembrar desses detalhes esotéricos, ele faria um teste colocando dígitos árabes, chineses ou hebraicos. Mas meros mortais não fazem isso.[/quote]

A situação que você descreve vale para qualquer código. Programadores melhores escrevem testes melhores. Isso não diminui o valor dos testes em si.[/quote]

Concordo. Mas o negócio é que regex pecam em legibilidade, em manutenibilidade e em “whatafucking shit black magic is that?”.

Com certeza. Esses são motivos inclusive para se escrever mais testes! :wink:

Pelo amor de Deus, programador Java é uma florzinha mesmo. Peca em legibilidade? Tá loco? É uma forma super concisa e clara de expressar uma seqüência de texto.

Você prefere usar indexOf, length, substring e outras porcarias?

"

[quote=Thiagosc]Pelo amor de Deus, programador Java é uma florzinha mesmo. Peca em legibilidade? Tá loco? É uma forma super concisa e clara de expressar uma seqüência de texto.

Você prefere usar indexOf, length, substring e outras porcarias?[/quote]

Realmente, super legível. Batendo o olho nisso, em apenas alguns milisegundos, você vê exatamente o que faz sem ficar com a menor dúvida: \b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b

Viu, é tão óbvio! Qualquer criança de 5 anos consegue entender perfeitamente de tão grande que é a legibilidade!

Sim, é normalmente a forma mais concisa de expressar uma seqüência e normalmente é a mais eficiente. Mas quanto a clareza, isso eu discordo.

"

http://xkcd.com/208/

Bem pessoal, eu não estou dizendo que regex seja ruim, já trabalhei com ele mas muitas vezes agente esquece porquê não é o tempo todo que usamos, eu agora estava usando pra capturar uma parte específica de uma exceção retornada.

O problema é a legibilidade. Perdemos muito tempo com isso e isso é um problema. Quem aqui vai me dizer que prefere a atual sintaxe do que uma sintaxe mais… orientada a objetos? Isso é algo a se pensar…

E bem, eu não tenho nem 10 min pra perder aqui no projeto. Porquê aqui o esquema é cada prazo atrasado é um pinto cortado.

Regex tem um ponto legal que é ter uma sintaxe quase unica entre todas as linguagens, mas e se isso fosse feito por XML? Criar um XML mais legivel que no final resulte em um Regex. Não sei, desculpem-me se estou falando alguma abobrinha.

Fica aí a crítica, se muitos consideram isso um problema, seria legal (e se alguém se dispusesse) poderiamos talvez pensar em algum jeito de melhorar isso… Não sei, só uma sugestão. (tenho que apresentar meu TCC daqui a 2 anos mesmo :P).

Abraços!

Há alguns lugares onde se proíbe o uso de certos recursos em projetos sob alegação de que dificultam a manutenção; o problema é que as alternativas (por exemplo, usar outras coisas em lugar de expressões regulares) podem acabar tornando os projetos com manutenção mais difícil.

O problema é que o uso de recursos mais avançados requer programadores mais experientes, que saibam o que estão fazendo.

Por exemplo, o abuso de expressões regulares de fato torna seus programas de manutenção impossível (isso normalmente é feito quando se aprende um recurso e se quer usá-lo em todos os lugares); eu mesmo evito usar as expressões regulares mais complicadas, e abuso dos comentários explicativos nas expressões, como vocês devem ter visto em um post acima.

E há coisas nas quais o uso de expressões regulares não é adequado.
Por exemplo, efetuar o parse de HTML não deve ser feito usando-se expressões regulares e sim um verdadeiro parser de HTML.
Outra coisa é avaliar expressões aritméticas, onde é necessário contar parênteses. Como vocês devem saber, expressões regulares não sabem contar.

Bem eu aprendi a gostar de RegEx, principalmente na versão 3 do CajuScript onde o parse passou a ser feito com RegEx, e tive que fazer varias RegEx para conseguir atingir o objetivo de ter um parser dinâmico usando RegEx.

Thingol, quanto ao problema de contar parênteses, no CajuScript fiz uma RegEx para pegar apenas o grupo simples de parenteses, e depois com um método recursivo vou pegando e substituindo os grupos e validando o que esta dentro de cada grupo e subgrupo de parenteses.

Só quero dizer com isto, que RegEx é uma mão na roda, e claro que não devemos usar RegEx pra tudo, e RegEx não faz tudo, como os problemas que o Thingol citou, mas é uma questão de fazer uma boa combinação de Programação + RegEx.

Eu antigamente também tinha uma má impressão de RegEx, principalmente no aspecto, mas depois que meti a cara ficou muito clara, e acho até intuitiva dentro do possível.

É tudo uma questão de hábito, e hoje em dia para ser um bom programador acho que é essencial dominar RegEx, é preciso colocar a preguiça e preconceito de lado e dedicar um tempo para estudar a fundo, e depois pode-se dar opiniões mais consistentes.

Muitas das opiniões aqui, especialmente as opiniões negativas, parecem ser na maioria de pessoas que ainda não estudaram RegEx, por isso friso isto, estudem, tentem compreender, e depois opinem melhor. Que só a primeira vista, é fácil opinar negativamente.

Não que seja um saco mas facilita em bem algumas validações
Como thingol disse qndo há uma validação bem complexa pense bem em utiliza-la.

A principal dificuldade que vejo as pessoas enfrentarem ao lidar com regex diz respeito a maneira de pensar: programadores normalmente pensam demais no COMO funciona/executa/resolve, e muito pouco no QUE algo é.

No caso do regex, o raciocínio que deve ser seguido é o do QUE. O QUE você quer encontrar, não COMO quer encontrar.

Argh - no meu tempo isso seria resolvido usando-se um “parser generator”, como o ANTLR ( http://www.antlr.org/ ); isso para mim é abuso do pacote java.lang.regex.
De qualquer maneira, muitos dos arquivos de especificação de gramáticas para “parser generators” usam uma notação de expressões regulares para especificar os tokens, veja o JLex ( http://www.cs.princeton.edu/~appel/modern/java/JLex/current/manual.html ).

Ninguém aqui jamais usou Perl.

[quote=thingol][quote=eduveks]
Thingol, quanto ao problema de contar parênteses, no CajuScript fiz uma RegEx para pegar apenas o grupo simples de parenteses, e depois com um método recursivo vou pegando e substituindo os grupos e validando o que esta dentro de cada grupo e subgrupo de parenteses.
[/quote]

Argh - no meu tempo isso seria resolvido usando-se um “parser generator”, como o ANTLR ( http://www.antlr.org/ ); isso para mim é abuso do pacote java.lang.regex.
De qualquer maneira, muitos dos arquivos de especificação de gramáticas para “parser generators” usam uma notação de expressões regulares para especificar os tokens, veja o JLex ( http://www.cs.princeton.edu/~appel/modern/java/JLex/current/manual.html ). [/quote]

Pois é… eu sei… mas para o CajuScript poder ser flexivel ao ponto que queria, precisava de um parser a medida e então preferi abraçar o desafio de criar um parser.

E outro ponto importante no CajuScript é não ter dependencias, qualquer bug, qualquer problema, qualquer idéia inovadora, não há bloqueios pois é tudo código próprio, e dá para fazer a medida sem rodeios.

Claro que há boas soluções, mas eu prefiro fazer de cabo a rabo quando é um projeto a este nível. Podes pensar que é reinventar a roda, mas eu vejo mais como melhorar a roda.

Obrigado pelas dicas estou olhando isto e tentar aproveitar algumas idéias.

[quote=eduveks][quote=thingol][quote=eduveks]
Thingol, quanto ao problema de contar parênteses, no CajuScript fiz uma RegEx para pegar apenas o grupo simples de parenteses, e depois com um método recursivo vou pegando e substituindo os grupos e validando o que esta dentro de cada grupo e subgrupo de parenteses.
[/quote]

Argh - no meu tempo isso seria resolvido usando-se um “parser generator”, como o ANTLR ( http://www.antlr.org/ ); isso para mim é abuso do pacote java.lang.regex.
De qualquer maneira, muitos dos arquivos de especificação de gramáticas para “parser generators” usam uma notação de expressões regulares para especificar os tokens, veja o JLex ( http://www.cs.princeton.edu/~appel/modern/java/JLex/current/manual.html ). [/quote]

Pois é… eu sei… mas para o CajuScript poder ser flexivel ao ponto que queria, precisava de um parser a medida e então preferi abraçar o desafio de criar um parser.

E outro ponto importante no CajuScript é não ter dependencias, qualquer bug, qualquer problema, qualquer idéia inovadora, não há bloqueios pois é tudo código próprio, e dá para fazer a medida sem rodeios.

Claro que há boas soluções, mas eu prefiro fazer de cabo a rabo quando é um projeto a este nível. Podes pensar que é reinventar a roda, mas eu vejo mais como melhorar a roda.

Obrigado pelas dicas estou olhando isto e tentar aproveitar algumas idéias.[/quote]

Eu acho que no seu caso, um parser de uma gramática livre de contexto seria bem melhor.

Isso aqui parece interessante: https://regexbuilder.dev.java.net/