Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

quoted-printable, and ugly code

by philth (Initiate)
on Feb 22, 2001 at 14:59 UTC ( [id://60180]=perlquestion: print w/replies, xml ) Need Help??

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

Is there any way I can write this better (I'm still learning perl):

if ( $_ =~ /From:/ ) { my $line = $_; my @addr; $line =~ s/^\w+\:(.*)$/$1/gs; push(@addr, Mail::Address->parse($line)); $address = $addr[0]->address(); $debug_text .= "Found address at line $.: $string\n"; }


And while I'm here, how does one decode quoted-printable encoded text? (ie, the sort that comes in emails)

Thanks.

Replies are listed 'Best First'.
Re: quoted-printable, and ugly code
by arhuman (Vicar) on Feb 22, 2001 at 15:03 UTC

    Slightly modified/simplified it gives :
    if ( /From:/ ) { s/^\w+\:(.*)$/$1/gs; push my @addr, Mail::Address->parse($_); $address = $addr[0]->address(); $debug_text .= "Found address at line $.: $string\n"; }

    I only use the fact that m// (ie //) and s// use $_ as default argument...
    (So using $line is useless)

    But what is $string ?

    MIME::QuotedPrint is probably (one of) the answer(s) to your second question...
      Might this work as well and be further simplified?
      if (/From:/) { m/^\w+:(\S+)$/ && push my @addr, Mail::Address->parse($1); $address = $addr[0]->address; $debug_text .= "Found $address at line $.\n"; }
      two notes. first, I dont see mention of $string anywhere so I am assuming you meant $address. second, im not sure why you needed to modify $_, when you could just stuff the match into $1, etc. third, semantically I didnt see any reason to say "Found address" when its clear that's what this codelet is doing. :) ymmv of course. also, from perldoc perlop:
      s/PATTERN/REPLACEMENT/egimosx s Treat string as single line. g Replace globally, i.e., all occurrences.
      not quite sure why youre using either switch since youre matching a "From: foo@bar.com" not a "From: foo@bar.com baz bletch blah blah From: bar@brak.org".

      sorry, this wasnt meant to be a round of perl golf, but there were a few simplifications i caught. :)

      brother dep.

      minor update:

      would it be possible to just do this?

      if (/^From:(\S+)$/) { push my @addr, Mail::Address->parse($1); $address = $addr[0]->address; $debug_text .= "Found $address at line $.\n"; } else { next }

      --
      transcending "coolness" is what makes us cool.

        I would shrink:
        push my @addr, Mail::Address->parse($1); $address = $addr[0]->address; # to $address = (Mail::Address->parse($1))[0]->address;
        But that's because I kinda abhor such ephemeral temporary variables. At the very least, that push() is useless.

        japhy -- Perl and Regex Hacker
(tye)Re: quoted-printable, and ugly code
by tye (Sage) on Feb 22, 2001 at 20:20 UTC

    Lots of items already covered here. But I felt compelled to note that s/^\w+:(.*)$/$1/gs nearly makes me cringe (which is silly because it really isn't "bad" at all). First, s/^\w+://gs gets the point across much better, I think. Second, can't headers have "-" in them so don't you want [-\w]+? Third, I'd strip whitespace after the ":". So:

    s/^[-\w]+:\s*//gs

            - tye (but my friends call me "Tye")
      Better yet, I think you can get both the quoted-printable decoding you want and the mail header parsing you'd like with use MIME::Parser, part of the MIME-tools package.

      And if what you're doing is tinkering with a Perl-based mail filter, check out Mail::Audit.

      Peace,
      -McD

        MIME::Parser is a real heavyweight. MIME::Lite is a good alternative.


        Always keep a song in your heart.
        It's like karaoke for the voices in your head.
Re: (mischief) quoted-printable, and ugly code
by mischief (Hermit) on Feb 23, 2001 at 06:39 UTC
    I was trying to get my handicap down playing golf with myself and I came up with this:

    print "Found $1 at line $.\n" if s/^[-\w]+:\s*(.*?)\s*$/($address)=(Mail::Address->parse($1))->add +ress/eggs; # and spam

    But it doesn't work - I get:

    Can't call method "address" without a package or object reference

    Can anyone tell me what I'm doing wrong?

    disclaimer: My brain is a bit slow at the moment, I'm probably missing something very obvious. Sorry,

    Update: thanks to dws for spotting that I'd missed out the print line. I told you my brain is a bit slow. :-)

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (2)
As of 2024-04-26 04:23 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found