[Rio-pm] quote regular expression

Adriano Ferreira a.r.ferreira em gmail.com
Sábado Março 27 07:39:40 PDT 2010


2010/3/25 Tiago Peczenyj <tiago.peczenyj at gmail.com>:
> Humm... então /xxx/ é diferente de qr/xxx/ (e qr{xxx})

Digamos que tem mais mágica em /xxx/ do que em qr/xxx/.

> achei que eram similares. eita.

E são (similares).

Acontece que /xxx/ é a expressão regular usada como um operador (na
verdade, o operador m/xxx/). No grep

      grep { !/xxx/ } @values;

funciona como abreviação de

      grep { !( $_ =~ /xxx/ ) } @values;

enquanto qr/xxx/ é a expressão regular em si, um objeto. Então

      grep { !qr/xxx/ } @values

não é diferente de

      grep { !$any_object } @values;

e (em geral) $any_object é verdadeiro, logo este grep é tão inútil como

      grep { 0 } @values;

A coisa muda de figura se você reaparecer com o operador de matching

       grep { !($_ =~ qr/xxx/) } @values;

ou

       grep { $_ !~ qr/xxx/ } @values;

Pode soar complicado, mas a prática faz a perfeição e torna mais fácil
distinguir os usos que na superfície tem só uma diferença sutil. Você
usa em geral /xxx/ para expressões regulares fixas em seu código e
qr/xxx/ é o que você precisa quando quer passar a regex como parâmetro
de subrotinas, valor em estruturas de dados, etc. e tal

Você pode ler mais a respeito disto em "perlop", seção "Regexp
Quote-Like Operators".

      $ perldoc perlop

Adriano

>
> Realmente neste caso eu deveria usar um getopts mas é um codigo legado
> que eu JA estraguei, prefiro ser cauteloso.
>
> 2010/3/25 breno <breno at rio.pm.org>:
>> 2010/3/25 Tiago Peczenyj <tiago.peczenyj at 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
>> _______________________________________________
>> Rio-pm mailing list
>> Rio-pm at pm.org
>> http://mail.pm.org/mailman/listinfo/rio-pm
>>
>
>
>
> --
> Tiago B. Peczenyj
> Linux User #405772
>
> http://pacman.blog.br
> _______________________________________________
> Rio-pm mailing list
> Rio-pm at pm.org
> http://mail.pm.org/mailman/listinfo/rio-pm
>


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