Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

match lines containing state abbreviation

by PerlSufi (Pilgrim)
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; }

Comment on match lines containing state abbreviation
Download Code
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.


    Dave

Re: match lines containing state abbreviation
by kcott (Abbot) 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

      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

      this worked
      my $match = "AZ"; my $content = $mech->content; my @lines = split /^/, $content; my @keepers = grep {/\Q$match\E/} @lines; print @keepers;

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1029390]
Approved by kcott
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (6)
As of 2014-09-21 13:45 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (171 votes), past polls