2

我正在尝试提出将拆分全名的正则表达式。

第一部分是验证 - 我想确保名称与模式“名称名称”或“名称 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。

4

4 回答 4

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 而是 az)

更新 1

数字组不适用于没有首字母的情况,所以我从头开始编写正则表达式

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

\w 代表任何单词字符,这可能是您需要的(如果效果更好,您可以将其替换为 az)

更新 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;
于 2012-06-06T23:11:13.720 回答
0

您可以通过在左括号之前添加当前的第二个捕获组成为非捕获组?:,然后将整个第二组移动到第一组的末尾来完成此操作,因此它将变为以下内容:

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

请注意,我也替换了{0,1}with ?,因为它们是等价的。

这将产生两个捕获组,一个用于名字和中间名首字母(如果存在),一个用于姓氏。

于 2012-06-06T23:13:07.100 回答
0

我不确定你是否想要这种方式,但有一种方法可以不用正则表达式。

如果名称的形式为Name Namethen 你可以这样做:

// 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 MINamethen 你可以这样做:

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

希望这可以帮助!

于 2012-06-06T23:13:18.370 回答
0

只需将可选部分放在第一个捕获组中:

(?i)^([a-z]+(?:\s[a-z]\.?)?)\s([a-z'-]+)$
于 2012-06-06T23:14:30.973 回答