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

This works for grepping for the From and Subject fields of an email and grabbing the matched string, but it seems clunky to me:
@from = grep(/^From:/o, @header); $curFrom = $from[0]; @subject = grep(/^Subject:/o, @header); $curSubject = $subject[0];
Can anyone suggest a more efficient way? Thanks.

Replies are listed 'Best First'.
Re: Better way to get the results of grep()?
by ikegami (Patriarch) on Dec 09, 2009 at 18:10 UTC
    my %headers = map split(/: /, $_, 2), @headers; my ($from, $subject) = @headers{qw( From Subject )};
Re: Better way to get the results of grep()?
by moritz (Cardinal) on Dec 09, 2009 at 17:34 UTC
    my @looking_for = qw(Subject From); my $re = join '|', map quotemeta, @looking_for; $re = qr{^($re):}; my %header; for (@header) { if ($_ =~ $re) { push @{$header{$1}}, $_; } } my $curFrom = $header{From}[0]

    The nice thing about this solution is that it scales well if you're looking for many different headers.

    Update: fixed thinko in code, AnomalousMonk++

    Perl 6 - links to (nearly) everything that is Perl 6.
Re: Better way to get the results of grep()?
by afoken (Chancellor) on Dec 09, 2009 at 19:25 UTC

    Do you know that logical mail header lines can be split across several physical lines? Any simple grep would find only the first part of the header. Use MIME::Parser, that module also handles other ugly things like encoded headers.

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
      Do you know that logical mail header lines can be split across several physical lines?

      This is news to me. Can you provide a reference on this? Thanks!

Re: Better way to get the results of grep()?
by eye (Chaplain) on Dec 09, 2009 at 19:44 UTC
    Rather than using an intermediate array and saving its first element, you could save the first element from the list that grep produces.
    ($curFrom) = grep(/^From:/, @header); ($curSubject) = grep(/^Subject:/, @header);
    Note that using the 'o' modifier on the regular expression does not offer a benefit in this instance. It is only useful when the regular expression would be re-evaluated on each execution (as when it includes a variable).
Re: Better way to get the results of grep()?
by mirage4d (Novice) on Dec 09, 2009 at 19:43 UTC
    Thanks for the responses gang. I knew there had to be a better way.