2012-08-29 19 views
6

en un correo electrónico, se ve como un "de" o "a" campo puede contener una o más direcciones, cada dirección puede ser como "[email protected]" o "John D Jr <[email protected]>"direcciones de correo electrónico de análisis sintáctico para "de" y "a" campos en Ruby

así

un campo "de" puede parecerse a cualquiera de los siguientes:

"[email protected]" 

"[email protected], Bob Blue <[email protected]>" 

"Abe Allen <[email protected]>, [email protected]" 

"Abe Allen <[email protected]>, Bob Blue <[email protected]>" 

"Abe Allen <[email protected]>, Bob Blue <[email protected]>, [email protected]" 

y así sucesivamente.

Quiero analizar estos campos, extraer el correo electrónico de cada dirección si es válido y el nombre si está presente. Dado que no estoy familiarizado con el estándar de correo electrónico, me pueden faltar algunos casos de cómo se pueden ver los campos de direcciones. ¿Hay una biblioteca de Ruby que pueda hacer esto?

+1

El análisis y validación de direcciones de correo electrónico no es una tarea trivial. La gama de formatos es enorme, e incluso si una dirección es válida, es muy posible que sea una dirección falsa y no entregable. Consulte "[Sabía cómo validar una dirección de correo electrónico hasta que leí el RFC]" (http://haacked.com/archive/2007/08/21/i-knew-how-to-validate-an-email-address- until-i.aspx) "para un interesante artículo sobre el tema. También [artículo de Wikipedia] (http://en.wikipedia.org/wiki/Email_address) y [SMTP RFC] (http://tools.ietf.org/html/rfc5322) en sí. –

Respuesta

11

Sí, hay una joya para esto; se llama mail.

require 'mail' 

addresses = [] 
raw_addresses = Mail::AddressList.new("Abe Allen <[email protected]>, Bob Blue <[email protected]>, [email protected]") 

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

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

    addresses << address  
end 
+1

Gracias, esto funciona bien para mi caso de uso. Por cierto, creo que quisiste hacer "raw_addresses.addresses.each"? – foobar

+0

Sí, gracias. – deefour

0

Suponiendo que sus datos sigue los ejemplos que diste, esto debería funcionar:

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 "[email protected]"           
# => [{:user=>nil, :email=>"[email protected]"}] 

extract_emails "[email protected], Bob Blue <[email protected]>"      
# => [{:user=>nil, :email=>"[email protected]"}, {:user=>"Bob Blue", :email=>"[email protected]"}] 

extract_emails "Abe Allen <[email protected]>, [email protected]"      
# => [{:user=>"Abe Allen", :email=>"[email protected]"}, {:user=>nil, :email=>"[email protected]"}] 

extract_emails "Abe Allen <[email protected]>, Bob Blue <[email protected]>"   
# => [{:user=>"Abe Allen", :email=>"[email protected]"}, {:user=>"Bob Blue", :email=>"[email protected]"}] 

extract_emails "Abe Allen <[email protected]>, Bob Blue <[email protected]>, [email protected]" 
# => [{:user=>"Abe Allen", :email=>"[email protected]"}, {:user=>"Bob Blue", :email=>"[email protected]"}, {:user=>nil, :email=>"[email protected]"}] 
+0

OP dijo "No estoy familiarizado con el estándar de correo electrónico, me pueden faltar algunos casos de qué campos de dirección se pueden ver". ... –

+0

Claro, pero a menos que sus correos electrónicos o nombres de usuario incluyan "<" and ">", esto funcionará bien con todos los datos. Si pueden incluir estos, entonces básicamente tendrá que escribir un analizador. –

0

no sé de una biblioteca, pero si usted está tratando de obtener una lista de los mensajes de correo electrónico que usted puede hacer lo siguiente sí mismo. (Sin aliento a propósito)

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

Si desea hacer coincidir sus nombres y direcciones de correo electrónico, necesitará algo más.

Además, esto no funcionará si hay '<' o '>' en la dirección de correo electrónico, pero eso es bastante raro.

Cuestiones relacionadas