Question

Given the email address: "Jim" <jim@example.com>

If I try to pass this to MailAddress I get the exception:

The specified string is not in the form required for an e-mail address.

How do I parse this address into a display name (Jim) and email address (jim@example.com) in C#?

EDIT: I'm looking for C# code to parse it.

EDIT2: I found that the exception was being thrown by MailAddress because I had a space at the start of the email address string.

Was it helpful?

Solution

If you are looking to parse the email address manually, you want to read RFC2822 (https://tools.ietf.org/html/rfc822.html#section-3.4). Section 3.4 talks about the address format.

But parsing email addresses correctly is not easy and MailAddress should be able to handle most scenarios.

According to the MSDN documentation for MailAddress:

http://msdn.microsoft.com/en-us/library/591bk9e8.aspx

It should be able to parse an address with a display name. They give "Tom Smith <tsmith@contoso.com>" as an example. Maybe the quotes are the issue? If so, just strip the quotes out and use MailAddress to parse the rest.

string emailAddress = "\"Jim\" <jim@example.com>";

MailAddress address = new MailAddress(emailAddress.Replace("\"", ""));

Manually parsing RFC2822 isn't worth the trouble if you can avoid it.

OTHER TIPS

Works for me:

string s = "\"Jim\" <jim@example.com>";
System.Net.Mail.MailAddress a = new System.Net.Mail.MailAddress(s);
Debug.WriteLine("DisplayName:  " +  a.DisplayName);
Debug.WriteLine("Address:  " + a.Address);

The MailAddress class has a private method that parses an email address. Don't know how good it is, but I'd tend to use it rather than writing my own.

Try:

"Jimbo <jim@example.com>"

try: "Jim" <jim@example.com> not sure if it'll work, but that's how I generally see it in e-mail clients.

if you make the assumption there is always a space between the 2, you could just use String.Split(' ') to split it on the spaces. That would give you an array with the parts split.

so maybe like this:

string str = "\"Jimbo\" jim@example.com"
string[] parts = str.Trim().Replace("\"","").Split(' ')

An issue with this to check for is that if the display name has a space in it, it will be split into 2 or more items in your array itself, but the email would always be last.

Edit - you might also need to edit out the brackets, just add replaces with those.

I just wrote this up, it grabs the first well formed e-mail address out of a string. That way you don't have to assume where the e-mail address is in the string

Lots of room for improvement, but I need to leave for work :)

class Program
{
    static void Main(string[] args)
    {
        string email = "\"Jimbo\" <jim@example.com>";
        Console.WriteLine(parseEmail(email));
    }

    private static string parseEmail(string inputString)
    {
        Regex r = 
            new Regex(@"^((?:(?:(?:[a-zA-Z0-9][\.\-\+_]?)*)[a-zA-Z0-9])+)\@((?:(?:(?:[a-zA-Z0-9][\.\-_]?){0,62})[a-zA-Z0-9])+)\.([a-zA-Z0-9]{2,6})$");

        string[] tokens = inputString.Split(' ');

        foreach (string s in tokens)
        {
            string temp = s;
            temp = temp.TrimStart('<'); temp = temp.TrimEnd('>');

            if (r.Match(temp).Success)
                return temp;
        }

        throw new ArgumentException("Not an e-mail address");
    }
}

It's a bit "rough and ready" but will work for the example you've given:

        string emailAddress, displayname;
        string unparsedText = "\"Jimbo\" <jim@example.com>";
        string[] emailParts = unparsedText.Split(new char[] { '<' });

        if (emailParts.Length == 2)
        {
            displayname = emailParts[0].Trim(new char[] { ' ', '\"' });
            emailAddress = emailParts[1].TrimEnd('>');
        }
new MailAddress("jim@example.com", "Jimbo");

to parse out the string you gave:

string input = "\"Jimbo\" jim@example.com";
string[] pieces = input.Split(' ');
MailAddress ma = new MailAddress(pieces[1].Replace("<", string.Empty).Replace(">",string.Empty), pieces[0].Replace("\"", string.Empty));
string inputEmailString = "\"Jimbo\" <jim@example.com>";
string[] strSet =  inputEmailString.Split('\"','<','>');   

MailAddress mAddress = new MailAddress(strSet[0], strSet[2]);

To handle embedded spaces, split on the brackets, as follows:

string addrin = "\"Jim Smith\" <jim@example.com>";
char[] bracks = {'<','>'};
string[] pieces = addrin.Split(bracks);
pieces[0] = pieces[0]
  .Substring(0, pieces[0].Length - 1)
  .Replace("\"", string.Empty);
MailAddress ma = new MailAddress(pieces[1], pieces[0]);

So, this is what I have done. It's a little quick and dirty, but seems to work.

string emailTo = "\"Jim\" <jim@example.com>";
string emailRegex = @"(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|""(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*"")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])";
string emailAddress = Regex.Match(emailTo.ToLower(), emailRegex).Value;
string displayName = null;

try
{
    displayName = emailTo.Substring(0, emailTo.ToLower().IndexOf(emailAddress) - 1);
}
catch 
{
    // No display name 
}

MailAddress addr = new MailAddress(emailAddress, displayName);

Comments?

I don't code in this language, but I see two issues you might want to check:

1- You don't know exactly why it was rejected. On immediate possibility was that it has a blacklist for example.com.

2- The real solution you want is to probably implement a strict validator. Stack Overflow is probably a good place to develop this, because there are lots of people with practical experience.

Here are a couple things you need:

  1. trim whitespace and obviously cruft.
  2. parse into individual parts (display name, left-hand-side of address, right-hand side of address).
  3. validate each of these with a data structure specific validator. For example, the right-hand side needs to be a valid FQDN (or unqualified hostname if you are on a liberal mail system).

That's the best long-term approach to solving this problem.

I can suggest my regex-based solution for decoding email address field values ("From", "To") and field value "Subject"

https://www.codeproject.com/Tips/1198601/Parsing-and-Decoding-Values-of-Some-Email-Message

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top