Share via


Splitting first name, middle initial, last name, and suffix into two strings

Question

Thursday, November 15, 2018 9:38 PM

Hi all,

I have a list of user's names formatted as [firstname lastname], which I intend to use to query an Active Directory, where user's names are displayed as [lastname, firstname].

While the obvious solution would be to split the name by white spaces and rejoin it in reverse order... there are some irregular names that prevent this.

Name in List             |   Name in Active Directory
|
James T Kirk             |   Kirk, James T
John Williams II         |   William II, John
Martin Luther King Jr.   |   King Jr., Martin Luther 

The approach that I think may solve this dilemma is to create a string array of common suffixes, and compare the last word in each string to it, whereupon a match would get the last 2 words as the surname, and the rest as the first name.

However, I don't know how to achieve this using Split(), or RegEx(), or SubString(), because I can only get the second-to-last or last word, and not both combined unless I add them together myself.

Can someone point me in the right direction?

string fullname = "Martin Luther King Jr."

string firstname = string.Empty;
string lastname = string.Empty;

string[] suffix = { "i", "ii", "iii", "iv", "v", "vi", "vii", "viii", "ix", "x", "jr", "sr" }

foreach(string s in suffix) {
   if(fullname.Equals(suffix)){
      lastname = fullname.Split().Reverse().Take(2).First() + fullname.Split().Reverse().Take(2).Last();
   }
}

firstname = fullname.Replace(lastname, "");

return (string.Format("{0}, {1}", lastname, firstname).Trim());

Thanks!

All replies (4)

Friday, November 16, 2018 5:56 AM âś…Answered

Hi Thomas Lu (Wesgroup),

Thank you for posting here.

For your question, if you want the result of [lastname, firstname], please try the code below.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace test1
{
    class Program
    {
        static void Main(string[] args)
        {
            string fullname = "Martin Luther King Jr.";
            string firstname = string.Empty;
            string lastname = string.Empty;
            string[] suffix = { "i", "ii", "iii", "iv", "v", "vi", "vii", "viii", "ix", "x", "Jr.", "sr" };
            string[] m = fullname.Split(' ');//Represents an array of strings separated by spaces
            string m1 = m[m.Length - 1];//Represents the last string in Fullname(Jr.)
            string m2 = m[m.Length - 2];//Represents the second to last string in Fullname(King)
            foreach (string s in suffix)
            {
                if (m1==s)
                {
                    lastname = m2 +" "+ m1;
                }
            }
            firstname = fullname.Replace(lastname, "");
            Console.WriteLine("{0}, {1}", lastname, firstname);
            Console.ReadKey();
        }
    }
}

Result:

Best Regards,

Wendy

MSDN Community Support
Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact [email protected].


Friday, November 16, 2018 3:44 AM

Unfortunately splitting names is very much a heuristic solution. No amount of algorithms is going to be correct in all cases. My company, which has to do this kind of stuff for a living, has spent years trying to come up with reasonable rules that work with multi part names and there simply isn't a guaranteed algorithm that works.

My personal recommendation is that you use string split to get the name parts. If you have 2 parts then it is likely a first/last name pair but note that singular names do exist. If there is more than one name then the it could be any combination of first/last name pairs and suffixes or middle names or initials. At this point it seems like you should just error out and require manual processing. But if that isn't an option then you could try to see if a suffix is involved. If so then ignore it (but it could be in AD that way). Using Split you can get the # of matches via the Length of the array. To get the last one then use LastOrDefault(). Then compare that against your list of suffixes. If it matches then ignore that part.

Start with the last name and try to find a match against that in AD using contains. You can get the list of partial matches and then try to match against the first name (again like). Alternatively you could try to find an exact match by last name and then compare the first name. If no matches are found then take the last 2 name parts and search, then compare against first. Repeat until you run out of name parts. Then you should likely go the other way. This is going to be painfully slow. At some point though you're going to find names that you cannot match. 

Michael Taylor http://www.michaeltaylorp3.net


Friday, November 16, 2018 4:35 AM

I agree with CoolDadTx, although I don't have the same experience in the field.

I would add that, if possible, you should try and keep all the possible parts of the names separated in the first place. So the user enters given name, surname, middle name(s), title, post-nominals, and so on, as separate fields and the problem doesn't arise. If you try working on a single string that can represent all possibilities, you're in for a long frustrating journey.

Remember, as just one complicating possibility, it's possible to have surnames (and occasionally given names) with spaces in them. So a name like "John Smith Jones" could be;

given name = John, middle name = Smith, surname = Jones

or

given name = John, surname = Smith Jones

or (less likely but still possible)

given name = John Smith, surname = Jones


Friday, November 16, 2018 5:17 PM

Hi CoolDadTx,

I completely agree with you about the impossibility to come up with an algorithm.

Fortunately, I think I've since come up with a "cheat" for the purpose of what I need to do.

Instead of trying to convert the [firstname lastname] from the list into [lastname, firstname] to perform an Active Directory search, I decided to do the following:

- create a List<Dictionary> of Dictionary<[firstname lastname], samAccountName>, where the key was created by getting and splitting each Active Directory object's name and rearranging.

- matching the [firstname lastname] from the list to the key in the Dictionary, and getting its samAccountName value

- perform the Active Directory search using the samAccountName value

For the purpose of the original question though, Wendy's suggestion has been marked as the answer.