我正在尝试使用正则表达式来分割全名。
第一部分是验证 - 我想确保名称与“名称名称”或“名称MI名称”模式匹配,其中MI可以是一个字符,可选地后跟句点。这消除了像“Jose Jacinto De La Pena”这样复杂的名字 - 这很好。我想出的表达是^([a-zA-Z]+\s)([a-zA-Z](\.?)\s){0,1}([a-zA-Z'-]+)$
,它似乎可以完成这项工作。
但是如何修改它以将名称分成两部分呢?如果存在中间首字母,我希望它成为第一个“名字”的一部分,换句话说,“James T. Kirk”应该分成“James T.”和“柯克”。 TIA。
答案 0 :(得分:3)
只需添加一些括号
^(([a-z]+\s)([a-z](\.?))\s){0,1}([a-z'-]+)$
您的比赛现在将在第1组
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
}
另外,我使正则表达式不敏感,以便你可以缩短它(没有a-zA-Z但是a-z)
更新1
对于没有初始化的情况,数字组不能很好地工作,所以我从sratch写了正则表达式
^(\w+\s(\w\.\s)?)(\w+)$
\ w代表任何单词字符,这可能是你需要的(如果效果更好,你可以用a-z替换它)
更新2
C#中有一个很好的功能,您可以在其中命名您的捕获
^(?<First>\w+\s(?:\w\.\s)?)(?<Last>\w+)$
现在您可以按名称而不是数字来引用该组(认为它更具可读性)
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;
答案 1 :(得分:0)
您可以通过在开始括号之前添加?:
,然后将整个第二组移动到第一组的末尾,将目前的第二个捕获组设为非捕获组来实现此目的,它会变成以下:
^([a-zA-Z]+\s(?:[a-zA-Z](\.?)\s)?)([a-zA-Z'-]+)
请注意,我还将{0,1}
替换为?
,因为它们是等效的。
这将产生两个捕获组,一个用于名字和中间名(如果存在),另一个用于姓氏。
答案 2 :(得分:0)
我不确定你是否想要这种方式,但有一种方法可以在没有正则表达式的情况下进行。
如果名称的格式为Name Name
,那么您可以这样做:
// 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];
如果名称的格式为Name MIName
,那么您可以这样做:
string firstName = fullName.Split('.')[0] + ".";
string lastName = fullName.Split('.')[1].Trim();
希望这有帮助!
答案 3 :(得分:0)
只需将可选部分放在第一个捕获组中:
(?i)^([a-z]+(?:\s[a-z]\.?)?)\s([a-z'-]+)$