3

I am trying to take a list of eMail addresses along with first and last names and convert them to a CSV format. My eMail addresses are in the following format:

First, Last <email1@example.com>; First, Last <email2@example.com>;

The output I need is the following:

email1@example.com,email2@example.com

I am using the following code:

string[] addresses = addresses_Delimited.Split(new Char[] { '<', '>' });

addresses_Delimited is my list of addresses in the original format.

The problem is that it is not eliminating first and last names; instead it is returning first and last names as entries in the array addresses. So, addresses[0] = "First, Last", addresses[1] = "email1@example.com", and addresses[2] = "; First, Last". All first and last name entries after the first one have a semicolon in them.

How do I make string.Split remove all text outside "<" and ">"? Do I need to use something else?

ServerS
  • 452
  • 3
  • 15

5 Answers5

6

Rather than using a Split which does not care that the delimiters are paired up, use a regular expression like this:

<([^>]+)>

When you apply this regex to your input strings, you would capture the content of angular brackets into capturing group number 1:

var s = "First, Last <email1@example.com>; First, Last <email2@example.com>;";
Regex regex = new Regex(@"<([^>]+)>");
foreach (Match m in regex.Matches(s)) {
    Console.WriteLine(m.Groups[1]);
}

Demo.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
2

Split won't work in this case. You need to use Regular Expressions. Try this

// using System.Text.RegularExpressions;
// pattern = any number of arbitrary characters between < and >.
var pattern = @"\<(.*?)\>";
var matches = Regex.Matches(addresses_Delimited, pattern);

foreach (Match m in matches) {
    Console.WriteLine(m.Groups[1]);
}
Saagar Elias Jacky
  • 2,684
  • 2
  • 14
  • 28
0

Split by ";' first, then by "<" and ">".

string inputEmails = "First1, Last1 <email1@example.com>; First2, Last2 <email2@example.com>;";
string[] inputEmailsArray = inputEmails.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
foreach (string email in inputEmailsArray)
{
    string[] inputEmailArray = email.Split(new char[] { '<', '>' }, StringSplitOptions.RemoveEmptyEntries);
    foreach (string emailPart in inputEmailArray)
    {
        string s = emailPart;   // First1, Last1     // email1@example.com
    }
}
Carl Prothman
  • 1,461
  • 13
  • 23
0

You can do it with split - but it's really ugly:

var text = "First, Last <email1@example.com>; First, Last <email2@example.com>;";

var t = text.TrimEnd(';').Split(';');
foreach (var m in t)
{
    Console.WriteLine(m.Split('<')[1].TrimEnd('>'));
}

Use RegularExpression instead.

GreenEyedAndy
  • 1,485
  • 1
  • 14
  • 31
0

Assuming (and this is a big assumption) that there are no ; characters in any names or emails and that there are no , characters in any emails, this will work:

using System.Linq;
using System.Net.Mail;

...

var input = "First, Last <email1@example.com>; First, Last <email2@example.com>;";

var emails = String.Join(",", input
  .Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries)
  .Select(s => new MailAddress(s).Address));
allonhadaya
  • 1,297
  • 7
  • 19