[Rio-pm] quote regular expression

breno breno em rio.pm.org
Quinta Março 25 10:09:22 PDT 2010


2010/3/25 Tiago Peczenyj <tiago.peczenyj em gmail.com>:
> Ola
>
> Estou com uma duvida no quote regular expression qr
>
> vejam este exemplo
>
> my $dryrun = (grep qr/^-{1,2}dry/, @ARGV) ? 1 : 0;
> @ARGV = grep !/^-{1,2}dry/, @ARGV;
>
> print "ok $dryrun\n";
>
> foreach my $a (@ARGV){ print "> $a\n"; }
>
> $ perl a.pl -dry 1 2 3
> ok 1
>> 1
>> 2
>> 3
>
> neste exemplo eu filtro a opção -dry dos argumentos (ok, não preciso
> fazer assim mas.... ) porem se eu faço
>
> @ARGV = grep !qr/^-{1,2}dry/, @ARGV;
>
> o @ARGV fica vazio!  deveria ser equivalente grep !/xxx/ e grep
> !qr/xxx/  -> sendo que tentei colocar parentesis em tudo para ver se
> era questão de prioridade.
>
> alguem imagina o que houve?
>

Fala Pac!

Se eu entendi direito o que você quer (retornar tudo do ARGV que não
for '-dry' ou '--dry', o seu problema é justamente o qr//. A sua
afirmação de que grep !/xxx/ e grep !qr/xxx/ deveriam ser equivalentes
não está certa. O que acontece é que o grep recebe a lista e retorna
apenas os elementos para os quais a expressão (ou bloco) são avaliados
como verdadeiros. No caso, qr// não avalia nada, é só um operador que
define uma expressão regular qualquer, você não está aplicando a
expressão regular retornada a lugar algum, ou a variável alguma. A ER
pura, por outro lado é comparada por padrão com $_, ou seja, com cada
elemento que o grep recebe), e vc terá o resultado esperado como você
mesmo mostrou:

   @ARGV = grep !/^-{1,2}dry/, @ARGV;

   print "@ARGV\n";

O resultado:

perl tmp.pl -dry 1 2 3
1 2 3

perl tmp.pl 1 --dry 2 3
1 2 3

perl tmp.pl 1 2 ---dry 3
1 2 ---dry 3

Se você quiser montar a ER via qr//, pode fazer assim:

my $regex = qr/^-{1,2}dry/;
@ARGV = grep $_ !~ $regex, @ARGV;

Mas a sua avaliação anterior (@ARGV = grep !qr/^-{1,2}dry/, @ARGV;)
retorna vazio pq a expressão regular no qr// é construída com sucesso
e retorna verdadeiro, que vira falso quando vc nega o valor de retorno
(o "!" no início). Assim, como o elemento atual nem é testado e a
expressão dentro do grep sempre retorna falso, a lista volta vazia.

Espero ter ajudado :-)

[]s

-b


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