简体   繁体   中英

Parse emails from Address Book

Our application has an invite page where a user can import their address book. We're using an external service to get at them, so it just puts the results into a textarea. We started out just splitting the results by comma, and quickly figured out that wasn't going to work because of:

"Smith, Joe" <jsmith@example.com>, "Jackson, Joe" <jjackson@example.com>

It would work between the 2 entries, but also split inside them as well. Just wondering if there's a well known fool-proof way to make this work.

Maybe regex would work? I'm pretty bad that, could anyone tip me off to what regex would extract just the emails into an array...

Something like this:

emails = recipients.scan(/.*@.*/) <<==== but i know that's not right

EDIT

Looks like something like this might work. Anyone have any suggestions if this would work for special cases:

emails = recipients.scan(/[a-z0-9_.-]+@[a-z0-9-]+\.[a-z.]+/i)
ruby-1.9.3-p0 :055 >   a = '"Smith, Joe" <jsmith@example.com>, "Jackson, Joe" <jjackson@example.com>';
ruby-1.9.3-p0 :056 >   b = a.scan(/<(.*?)>/).flatten
 => ["jsmith@example.com", "jjackson@example.com"] 
ruby-1.9.3-p0 :057 > c = a.scan(/"(.*?)"/).flatten
 => ["Smith, Joe", "Jackson, Joe"] 

The index of name / email in each array is the same, thus c[1] is the name for the b[1] email.

Based on your comment how about his :

ruby-1.9.3-p0 :008 > a = '"Smith, Joe" <jsmith@example.com>, "Jackson, Joe" <jjackson@example.com>';
ruby-1.9.3-p0 :009 >   b = '"test@domain.com, test2@domain.com"';
ruby-1.9.3-p0 :010 >   b.scan(/\w*@\w*\.\w*/)
 => ["test@domain.com", "test2@domain.com"] 
ruby-1.9.3-p0 :011 > a.scan(/\w*@\w*\.\w*/)
 => ["jsmith@example.com", "jjackson@example.com"] 

Which is pretty much the same as you added to your question, just more compact.

Kassym's version will fail in all sorts of circumstances, including on any email addresses that contain non-word characters (eg some.guy@gmail.com )

Parsing email lists can't be done with regular expressions. Use something with a real parser, like the mail gem:

require "mail"

Mail::AddressList.new(address_list).addresses.map(&:address)

EZ!

You could try to split with the following regex

,(?=(?:[^"]*"[^"]*")*[^"]*$)

Altho this is not an optimal quick solution, and could be slow for longs strings, better to use a specialized parser. Quoted quotes could be a problem with this solution, depending on how they are escaped (if at all).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM