Lyndley has asked for the wisdom of the Perl Monks concerning the following question:

Could anyone offer some advice on the following.

The below code demonstrates the problem. Basically arrays @a and @b are the same so as the program iterates through array @a checking each value against array @b, grep should return true every time.

Trouble is it doesn't seem to when unusual characters are in the string, in this example brackets chars ( or ).

I'm sure this is something to do with the string being expanded inside the grep statment before grepping occurs but I'd just like to understand if this *is* why it's going wrong just why does it do it like that and what's the best way around it.

I wouldn't like to have to escape every character before grepping if at all possible.

Thanks.

use strict; my (@a,@b); @a=@b=("test1","test2(X)"); foreach(@a) { my $x=$_; if(grep(/^$x$/,@b)) { print "\"$x\" exists in \"@b\"\n"; } else { print "\"$x\" doesn't exist in \"@b\"\n"; } }

Replies are listed 'Best First'.
Re: Grep expansion problem
by Codon (Friar) on Sep 07, 2005 at 17:00 UTC
    Is there a specific reason for doing an exact match via regex when an equality check would suffice?
    if ( grep $_ eq $x, @b ) { ... }
    This would be faster and would not be vulnerable to metacharacter interpolation.

    Ivan Heffner
    Sr. Software Engineer, DAS Lead
    WhitePages.com, Inc.
      Well it's just a proof of problem script. ;)

      Cheers all =)

Re: Grep expansion problem
by chester (Hermit) on Sep 07, 2005 at 16:51 UTC
    If you change the regex to /^\Q$x\E$/ it works. \Q..\E stops the regex from interpreting the parens as metacharacters.
Re: Grep expansion problem
by sk (Curate) on Sep 07, 2005 at 16:54 UTC
    my $x=quotemeta($_); __END__ "test1" exists in "test1 test2(X)" "test2\(X\)" exists in "test1 test2(X)"