简体   繁体   中英

Parse email addresses for “from” and “to” fields in Ruby

In an email, it looks like a "from" or "to" field can contain one or more addresses, each address can be like "john@test.com" or "John D Jr <john@test.com>"

So a "from" field can look like any of the following:

"a@a.com"

"a@a.com, Bob Blue <b@b.com>"

"Abe Allen <a@a.com>, b@b.com"

"Abe Allen <a@a.com>, Bob Blue <b@b.com>"

"Abe Allen <a@a.com>, Bob Blue <b@b.com>, c@c.com"

and so on.

I want to parse these fields, extracting each address' email if it's valid, and the name if it's present. Since I'm not familiar with the email standard, I may be missing some cases of what address fields can look like. Is there a Ruby library that can do this?

Yes, there's a gem for this; it's called mail .

require 'mail'

addresses = []
raw_addresses = Mail::AddressList.new("Abe Allen <a@a.com>, Bob Blue <b@b.com>, c@c.com")

raw_addresses.addresses.each do |a|  
  address = {}

  address[:address] = a.address
  address[:name]    = a.display_name if a.display_name.present?

  addresses << address      
end

Assuming your data follows the examples you gave, this should work:

def extract_emails(string)
  string.split(', ').map do |user_string|
    if user_string.include? '<'
      user_string =~ /^([^<]*)<([^>]*)>$/
      {user: $1.strip, email: $2}
    else
      {user: nil, email: user_string}
    end
  end
end

extract_emails "a@a.com"                                          
# => [{:user=>nil, :email=>"a@a.com"}]

extract_emails "a@a.com, Bob Blue <b@b.com>"                      
# => [{:user=>nil, :email=>"a@a.com"}, {:user=>"Bob Blue", :email=>"b@b.com"}]

extract_emails "Abe Allen <a@a.com>, b@b.com"                     
# => [{:user=>"Abe Allen", :email=>"a@a.com"}, {:user=>nil, :email=>"b@b.com"}]

extract_emails "Abe Allen <a@a.com>, Bob Blue <b@b.com>"          
# => [{:user=>"Abe Allen", :email=>"a@a.com"}, {:user=>"Bob Blue", :email=>"b@b.com"}]

extract_emails "Abe Allen <a@a.com>, Bob Blue <b@b.com>, c@c.com" 
# => [{:user=>"Abe Allen", :email=>"a@a.com"}, {:user=>"Bob Blue", :email=>"b@b.com"}, {:user=>nil, :email=>"c@c.com"}]

I don't know of a library, but if you are trying to get a list of the emails you could do the following yourself. (Long winded on purpose)

@a = "Abe Allen <a@a.com>, Bob Blue <b@b.com>, c@c.com"
b = @a.split(',') #=> ["Abe Allen <a@a.com>", " Bob Blue <b@b.com>", " c@c.com"] 
c = b.collect{|x| x[/<(.*?)>|^([^<>]*)$/]} #=> ["<a@a.com>", "<b@b.com>", " c@c.com"] 
d = c.gsub(/[<>]/,'') #=> ["a@a.com", "b@b.com", " c@c.com"] 

If you want to match their names and email addresses, you will need something else.

Also, this won't work if there are '<' or '>' in the email address, but that's pretty uncommon.

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