17

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.

Dylan
  • 2,392
  • 6
  • 26
  • 34
  • May I suggest MimeKit? It's a very standards-compliant library capable of parsing email addresses correctly. – Roy Tinker Aug 31 '16 at 22:55
  • Possible duplicate of [How To Parse String in format "Name "](http://stackoverflow.com/questions/12442635/how-to-parse-string-in-format-name-email) – Michael Freidgeim Jan 30 '17 at 04:15

14 Answers14

21

If you are looking to parse the email address manually, you want to read RFC2822 (https://www.rfc-editor.org/rfc/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.

Community
  • 1
  • 1
Brannon
  • 25,687
  • 5
  • 39
  • 44
  • 1
    Cool - I never know you could just send in 'Name '! I was just about to write another string splitting function :) – TimS Nov 05 '09 at 10:43
  • 2
    Maybe it helps someone, i had to use it with this slight difference because it wouldn't accept an empty char, because every possible value for a char type is one character long. `MailAddress address = new MailAddress(emailAddress.Replace("\"", ""));` – Soph Jun 11 '12 at 13:55
5

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.

Joe
  • 122,218
  • 32
  • 205
  • 338
2

Try:

"Jimbo <jim@example.com>"
Codewerks
  • 5,884
  • 5
  • 29
  • 33
0
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));
Wayne
  • 38,646
  • 4
  • 37
  • 49
0

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

Sekhat
  • 4,435
  • 6
  • 43
  • 50
0
string inputEmailString = "\"Jimbo\" <jim@example.com>";
string[] strSet =  inputEmailString.Split('\"','<','>');   

MailAddress mAddress = new MailAddress(strSet[0], strSet[2]);
Vivek
  • 16,360
  • 5
  • 30
  • 37
0

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.

Carlton Jenke
  • 2,975
  • 3
  • 26
  • 30
0

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");
    }
}
FlySwat
  • 172,459
  • 74
  • 246
  • 311
0

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('>');
        }
Rob
  • 45,296
  • 24
  • 122
  • 150
0

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]);
b w
  • 4,553
  • 4
  • 31
  • 36
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?

Dylan
  • 2,392
  • 6
  • 26
  • 34
0

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.

benc
  • 1,381
  • 5
  • 31
  • 39
0

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

0

If you are using MailKit, as recommended, then you can use the methods Parse and TryParse of MimeKit.MailboxAddress. Here's an example.

[Test]
public void Should_Parse_EmailAddress_With_Alias()
{
    //Arrange
    var expectedAlias = "Jim";
    var expectedAddress = "jim@example.com";
    string addressWithAlias = "\"Jim\" <jim@example.com>";

    //Act
    var mailboxAddressWithAlias = MimeKit.MailboxAddress.Parse(addressWithAlias);

    //Assert
    Assert.AreEqual(expectedAddress, mailboxAddressWithAlias.Address);
    Assert.AreEqual(expectedAlias, mailboxAddressWithAlias.Name);
}
pavok
  • 380
  • 3
  • 10