# Best way to parse email recipient lists?

**URL:** <https://www.ruby-forum.com/t/best-way-to-parse-email-recipient-lists/75390>\
**Category:** Ruby\
**Created:** [November 9, 2006, 4:52pm UTC](https://www.ruby-forum.com/t/best-way-to-parse-email-recipient-lists/75390 "2006-11-09T16:52:15Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![sbraford](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/82dd89/32.png) [@sbraford](https://www.ruby-forum.com/u/sbraford)\
**Post date:** [November 9, 2006, 4:52pm UTC](https://www.ruby-forum.com/t/best-way-to-parse-email-recipient-lists/75390/1 "2006-11-09T16:52:15Z")

</div>

Hey all,

So… I’m trying to parse email recipient lists (entered by hand into  
the “to”, “cc” and “bcc” fields of a mail app by users).

These can obviously come in a wild variety of formats, and I’d like to  
support as many as possible.

The other gotcha - is that I’d like to keep as much name metadata  
available as possible.

Using TMail’s parser - I was under the impression that the name portion  
in the “to”, “cc”, “bcc” fields gets stripped, down to an array of email  
addresses. (i.e. otherwise we could use just TMail - please let me know  
if this is incorrect or if there’s a work around)

Here are a few example scenarios (from relatively easy to a little  
harder):  
removed\_email\_address@domain.invalid  
removed\_email\_address@domain.invalid  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
“Bob S.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
Bob S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
“Jones, Craig” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
“Summer Thomas” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid); “Al Franken” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
“Clinton, Bill” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid); “Obama, Barack”  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid); “Jenny McCarthy” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
Bob [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid), [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid), James Blunt  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

etc…

Any ideas?

I’ve been working up RegEx’s like crazy but my RegEx foo isn’t quite  
what it used to be. Are there any shortcuts, or do I need one big RegEx  
many specific ones to match the various scenarios?

We’re currently using this RegEx to detect when we have a single  
properly formatted address (w/o a name attached):  
[http://tfletcher.com/lib/rfc822.rb](http://tfletcher.com/lib/rfc822.rb)  
…but that’s only one small portion of the problem.

- Shanti

---

<div class="post-metadata">

**Author:** ![sbraford](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/82dd89/32.png) [@sbraford](https://www.ruby-forum.com/u/sbraford)\
**Post date:** [November 9, 2006, 11:54pm UTC](https://www.ruby-forum.com/t/best-way-to-parse-email-recipient-lists/75390/2 "2006-11-09T23:54:39Z")

</div>

Shanti,

Try:

/(\W?([\w\s]+)\W+)?(\w[\w+-.]+@[\w-.]+)\W?/i  
(with “+” signs in mailbox (like removed\_email\_address@domain.invalid), which are  
invalid)

/(\W?([\w\s]+)\W+)?(\w[\w\-.]+@[\w-.]+)\W?/i  
(without “+” signs)

These should break the addresses down into arrays of matches that you  
can parse into:  
display name  
mailbox  
domain

Let me know if this doesn’t pass the tests. Better yet, send me a unit  
test and i’ll make it work. 🙂

also: [Ruby | zenspider.com | by ryan davis](http://www.zenspider.com/Languages/Ruby/QuickRef.html#11)

Michael Fleet  
Disinnovate  
[http://www.disinnovate.com/](http://www.disinnovate.com/)

---

<div class="post-metadata">

**Author:** ![sbraford](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/82dd89/32.png) [@sbraford](https://www.ruby-forum.com/u/sbraford)\
**Post date:** [November 10, 2006, 12:57am UTC](https://www.ruby-forum.com/t/best-way-to-parse-email-recipient-lists/75390/3 "2006-11-10T00:57:00Z")

</div>

On Fri, 10 Nov 2006, Shanti B. wrote:

> “Bob S.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
> Bob S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
> “Jones, Craig” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
> “Summer Thomas” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid); “Al Franken” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
> “Clinton, Bill” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid); “Obama, Barack”  
> [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid); “Jenny McCarthy” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
> Bob [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid), [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid), James Blunt  
> [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

```
 harp:~ > cat a.rb
 require 'tmail'
 require 'yaml'

 tmail = TMail::Mail::parse <<-msg
 From removed_email_address@domain.invalid Thu Nov 9 08:55:15 2006
 Date: Fri, 10 Nov 2006 00:52:17 +0900
 From: Shanti B. <removed_email_address@domain.invalid>
 Reply-To: removed_email_address@domain.invalid
 To: ruby-talk ML <removed_email_address@domain.invalid>
 Newsgroups: comp.lang.ruby
 Subject: Best way to parse email recipient lists?

 Hey all,

 So... I'm trying to parse email recipient lists (entered by hand 

```

into  
the “to”, “cc” and “bcc” fields of a mail app by users).  
msg

```
 %w( to from cc bcc ).each do |field|
   list = tmail.send("#{ field }_addrs") || []
   phrases = list.map{|a| a.phrase}

   y field => phrases.zip(list.map{|a| a.to_s})
 end

 harp:~ > ruby a.rb
 to:
 - - ruby-talk ML
   - ruby-talk ML <removed_email_address@domain.invalid>
 from:
 - - Shanti B.
   - Shanti B. <removed_email_address@domain.invalid>
 cc: []

 bcc: []

```

-a
