[Cascavel-pm] problema com regex

Wendel Scardua wendelscardua em gmail.com
Segunda Fevereiro 26 17:33:17 PST 2007


Bom o Nilson respondeu a parte Y do "problema XY", então vou responder sobre
a parte X (afinal é bom entender as regexes em geral, mesmo que não sejam
uma boa solução para esse caso específico).

Iberê, a questão é que não há "problema". Você pediu literalmente:

 li> seguido do máximo possível de qualquer coisa, seguido do máximo
possível de espaços, seguido de <br

Se você queria "li> seguido do mínimo possível de qualquer coisa, etc, etc"
deveria ter escrito /li>(.*?)\s*<br/ . Note o uso de *? (não-guloso) ao
invés de * (guloso).

Por outro lado, costuma ser ineficiente usar o operador não-guloso, então
você deveria preferir uma solução "gulosa", mas mais específica.

Por exemplo, suponha que o texto que você quer capturar entre li> e <br não
apresente nenhuma tag (isto é, nunca vai aparecer os caracteres < e  >) .
Então, você pode escrever uma regexp gulosa: /li>([^<>]*)<br/ , que
significa: pege li> , seguido do máximo possível de qualquer coisa (exceto <
e > ), seguido de <br.

Agora, só mais um detalhe que passou desapercebido, justamente pela confusão
com a gulodice do *. Na sua regexp você escreveu:

/li>(.*)\s*<br/

Eu suponho que você queria que a parte capturada não terminasse com espaços,
e que todos os espaços fossem pegos pelo /\s*/. Sinto muito, mas não é assim
que a coisa funciona. /.*/ vai bater com qualquer coisa, inclusive espaços -
mas em geral não o \n. Logo, o /.*/ vai pegar todos os espaços antes de
<br,  não deixando nenhunzinho pro /\s*/ .

Se usar o /.*?/ esse problema não ocorre, pois ele não é guloso, e o /\s*/
vai bater com todos os espaços.

Novamente, numa solução gulosa, basta dizer que não há um espaço à esquerda
do /\s*/, ficando:

/li>([^<>]*)(?<!\s)\s*<br/

onde (?<!\s) é uma "afirmação" que "bate" se à esquerda não bater /\s/ .

Sugiro dar uma lida na documentação de expressões regulares (perldoc perlre
, ou man perlre , ou google perlre :-) ).

Mas, no caso de tratar html, vale mais a pena usar módulos que fazem parsing
de html. Sugiro, por exemplo, o HTML::TreeBuilder (
http://search.cpan.org/~petek/HTML-Tree-3.23/lib/HTML/TreeBuilder.pm).

On 2/26/07, "Iberê O. Kuntz de Souza" <kuntzzz em gmail.com> wrote:
>
> Aee galera..
> to com um probeminha aqui. O codigo ta tipo assim:
>
> my $_ = '<li>isso eh um teste.<br><a href="www.lalala.com.br">UM MONTE
> DE COISA AQUI!!!!!<li>just another perl hacker.<br>hehehehehe';
> if ( /li>(.*)\s*<br/ ) { print $1,"\n" }
>
> o problema eh que quando executo ele pega ateh o ultimo '<br', send que
> eu quero que pare no primero, simplesmente pegando "isso eh um teste.".
> Obrigado.
> _______________________________________________
> Cascavel-pm mailing list
> Cascavel-pm em pm.org
> http://mail.pm.org/mailman/listinfo/cascavel-pm
>



-- 
[]s
Wendel

"Não ajustar o auto-ajuste" - http://wendel.scardua.net/
-------------- Próxima Parte ----------
Um anexo em HTML foi limpo...
URL: http://mail.pm.org/pipermail/cascavel-pm/attachments/20070226/c6d803ce/attachment-0001.html 


Mais detalhes sobre a lista de discussão Cascavel-pm