Reputation: 23
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
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
Reputation: 33908
Just put the optional part in the first capturing group:
(?i)^([a-z]+(?:\s[a-z]\.?)?)\s([a-z'-]+)$
Upvotes: 0
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
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