Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked

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
NodeReaper drums his fingers on the chair arm

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (6)
As of 2018-05-21 10:11 GMT
Find Nodes?
    Voting Booth?