ChrisH
ChrisH

Reputation: 23

Split name with a regular expression

I'm trying to come up with regular expression which will split full names.

The first part is validation - I want to make sure the name matches the pattern "Name Name" or "Name MI Name", where MI can be one character optionally followed by a period. This weeds out complex names like "Jose Jacinto De La Pena" - and that's fine. The expression I came up with is ^([a-zA-Z]+\s)([a-zA-Z](\.?)\s){0,1}([a-zA-Z'-]+)$ and it seems to do the job.

But how do I modify it to split the name into two parts only? If middle initial is present, I want it to be a part of the first "name", in other words "James T. Kirk" should be split into "James T." and "Kirk". TIA.

Upvotes: 2

Views: 6902

Answers (4)

buckley
buckley

Reputation: 14079

Just add some parenthesis

^(([a-z]+\s)([a-z](\.?))\s){0,1}([a-z'-]+)$

Your match will be in group 1 now

string resultString = null;
try {
    resultString = Regex.Match(subjectString, @"^(([a-z]+\s)([a-z](\.?))\s){0,1}([a-z'-]+)$", RegexOptions.IgnoreCase).Groups[1].Value;
} catch (ArgumentException ex) {
    // Syntax error in the regular expression
}

Also, I made the regex case insensitive so that you can make it shorter (no a-zA-Z but a-z)

Update 1

The number groups don't work well for the case there is no initial so I wrote the regex from sratch

^(\w+\s(\w\.\s)?)(\w+)$

\w stands for any word charater and this is maybe what you need (you can replace it by a-z if that works better)

Update 2

There is a nice feature in C# where you can name your captures

^(?<First>\w+\s(?:\w\.\s)?)(?<Last>\w+)$

Now you can refer to the group by name instead of number (think it's a bit more readable)

var subjectString = "James T. Kirk";
Regex regexObj = new Regex(@"^(?<First>\w+\s(?:\w\.\s)?)(?<Last>\w+)$", RegexOptions.IgnoreCase);

var groups = regexObj.Match(subjectString).Groups;
var firstName = groups["First"].Value;
var lastName = groups["Last"].Value;

Upvotes: 3

Qtax
Qtax

Reputation: 33908

Just put the optional part in the first capturing group:

(?i)^([a-z]+(?:\s[a-z]\.?)?)\s([a-z'-]+)$

Upvotes: 0

matthewr
matthewr

Reputation: 4739

I'm not sure if you want this way, but there is a method of doing it without regular expressions.

If the name is in the form of Name Name then you could do this:

// fullName is a string that has the full name, in the form of 'Name Name'
string firstName = fullName.Split(' ')[0];
string lastName = fullName.Split(' ')[1];

And if the name is in the form of Name MIName then you can do this:

string firstName = fullName.Split('.')[0] + ".";
string lastName = fullName.Split('.')[1].Trim();

Hope this helps!

Upvotes: 0

Andrew Clark
Andrew Clark

Reputation: 208465

You can accomplish this by making what is currently your second capturing group a non-capturing group by adding ?: just before the opening parentheses, and then moving that entire second group into the end of the first group, so it would become the following:

^([a-zA-Z]+\s(?:[a-zA-Z](\.?)\s)?)([a-zA-Z'-]+)

Note that I also replaced the {0,1} with ?, because they are equivalent.

This will result in two capturing groups, one for the first name and middle initial (if it exists), and one for the last name.

Upvotes: 0

Related Questions