Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?

match lines containing state abbreviation

by PerlSufi (Friar)
on Apr 18, 2013 at 17:19 UTC ( #1029390=perlquestion: print w/replies, xml ) Need Help??
PerlSufi has asked for the wisdom of the Perl Monks concerning the following question:

Hello monks, Here is my code. I have a list of lines with comma separated data. Eventually I need them in an Excel file- but first I need all the ones containing only AZ.
my $match = "AZ"; my $content = $mech->content; my @lines = split /^/, $content; my @keepers = grep { $match } @lines; foreach my $line (@keepers){ print $line; }

Replies are listed 'Best First'.
Re: match lines containing state abbreviation
by davido (Archbishop) on Apr 18, 2013 at 17:31 UTC

    Change your grep to do something useful.

    my @keepers = grep /^$match$/, @lines;

    ...for instance. The problem with your existing code is that $match, used as a simple expression, is simply evaluated in boolean context; if $match contains a value that Perl considers true, the expression will be true. Since "AZ", the string, is always true, every @lines gets grepped into @keepers.


Re: match lines containing state abbreviation
by kcott (Chancellor) on Apr 18, 2013 at 17:35 UTC

    G'day PerlSufi,

    In a boolean context, any non-zero-length string evaluates to TRUE. So the grep expression will always be TRUE and @keepers will be a copy of @lines.

    $ perl -Mstrict -Mwarnings -E ' my $match = "AZ"; my @lines = qw{AZ SX AZ DC}; my @keepers = grep { $match } @lines; say "@keepers"; ' AZ SX AZ DC

    What you need to do to filter @lines, is make the grep expression a regular expression (i.e. /$match/).

    $ perl -Mstrict -Mwarnings -E ' my $match = "AZ"; my @lines = qw{AZ SX AZ DC}; my @keepers = grep { /$match/ } @lines; say "@keepers"; ' AZ AZ

    -- Ken

      this worked
      my $match = "AZ"; my $content = $mech->content; my @lines = split /^/, $content; my @keepers = grep {/\Q$match\E/} @lines; print @keepers;
      Thanks for the response, Ken. That is helpful how you explained it. However, should I make the $content an array of lines to match? I have taken out the foreach operator right now..

        Splitting the lines to create an array is probably what I would have done. However, if you want to work directly with a multiline string, here's one way to do it:

        $ perl -Mstrict -Mwarnings -E ' my $lines = "AZ\nSX\nAZ\nDC\nAB\nYZ\n"; say $lines; $lines =~ s/(?>[^A].|.[^Z])\n//gm; say $lines; ' AZ SX AZ DC AB YZ AZ AZ

        In my opinion, the multiline solution is a lot more cryptic than the array solution.

        -- Ken

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1029390]
Approved by kcott
and the daffodils sway...

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (4)
As of 2017-12-17 22:10 GMT
Find Nodes?
    Voting Booth?
    What programming language do you hate the most?

    Results (466 votes). Check out past polls.