繁体   English   中英

正则表达式查找“​​姓氏,名字中间名”格式

[英]Regular Expression to find "lastname, firstname middlename" format

我试图找到格式“abc,def g”,这是一种名称格式“姓氏,名字中间名”。 我认为最适合的方法是正则表达式,但我对正则表达式一无所知。 我尝试在正则表达式中进行一些学习并尝试了一些表达,但没有运气。 另外一点,单词之间可能有不止一个空格。

这是我尝试过的。 但这不起作用。

(([A-Z][,]\s?)*([A-Z][a-z]+\s?)+([A-Z]\s?[a-z]*)*)

需要帮忙 ! 知道如何做到这一点,以便只有上面的表达式匹配。

谢谢 !

回答

最后我正在使用

([A-Za-z]+),\\s*([A-Za-z]+)\\s*([A-Za-z]+)

感谢大家的建议。

我会尽量避免使用复杂的正则表达式,我会使用String.substring()indexOf() 也就是说,像

String name = "Last, First Middle";
int comma = name.indexOf(',');
int lastSpace = name.lastIndexOf(' ');
String lastName = name.substring(0, comma);
String firstName = name.substring(comma + 2, lastSpace);
String middleName = name.substring(lastSpace + 1);
System.out.printf("first='%s' middle='%s' last='%s'%n", firstName,
            middleName, lastName);

输出是

first='First' middle='Middle' last='Last'

您的示例输入是"lastname, firstname middlename" - 这样,您可以使用以下正则表达式来提取姓氏、名字和中间名(此外,可能有多个空格,并且可能同时存在大写和非大写字符串中的字母 - 此外,所有部分都是强制性的):

String input = "Lastname,   firstname   middlename";
String regexp = "([A-Za-z]+),\\s+([A-Za-z]+)\\s+([A-Za-z]+)";

Pattern pattern = Pattern.compile(regexp);
Matcher matcher = pattern.matcher(input);
matcher.find();
System.out.println("Lastname  : " + matcher.group(1));
System.out.println("Firstname : " + matcher.group(2));
System.out.println("Middlename: " + matcher.group(3));

简短的摘要:

([A-Za-z]+)   First capture group - matches one or more letters to extract the last name
,\\s+         Capture group is followed by a comma and one or more spaces
([A-Za-z]+)   Second capture group - matches one or more letters to extract the first name
\\s+          Capture group is followed by one or more spaces
([A-Za-z]+)   Third capture group - matches one or more letters to extract the middle name

这仅在您的姓名仅包含拉丁字母时才有效 - 可能您应该对字符使用更开放的匹配:

String input = "Müller,   firstname  middlename";
String regexp = "(.+),\\s+(.+)\\s+(.+)";

这匹配姓氏、名字和中间名的任何字符。

如果空格是可选的(只有第一次出现可以是可选的,否则我们无法区分名字和中间名),那么使用*代替+

String input = "Müller,firstname  middlename";
String regexp = "(.+),\\s*(.+)\\s+(.+)";

正如@Elliott 所提到的,可能还有其他可能性,例如将String.split()String.indexOf()String.substring()一起使用 - 正则表达式通常更灵活,但更难维护,尤其是对于复杂的表达式。

在任何一种情况下,使用尽可能多的不同输入(包括无效输入)来实施单元测试,以便您可以验证您的算法在修改后仍然有效。

作为直接匹配lastname, firstname middlename的替代方法,您可以使用 String.split 并提供一个匹配分隔符的正则表达式。 例如:

static String[] lastFirstMiddle(String input){
    String[] result=input.split("[,\\s]+");
    System.out.println(Arrays.asList(result));
    return result;
}

我用输入测试了这个

"Müller,   firstname  middlename"
"Müller,firstname  middlename"
 "O'Gara, Ronan Ramón"

注意:这种方法对于包含空格的姓氏会失败,例如“van der Heuvel”、“de Valera”、“mac Piarais”或“bin Laden”,但话说回来,OP 的原始规范似乎不允许姓氏中有空格(或其他名字。我和“玛丽·凯特”一起工作。那是她的名字,不是名字和中间名)。 http://www.w3.org/International/questions/qa-personal-names上有一个关于个人姓名的有趣页面

^([a-zA-Z]+)\s*,\s*([a-zA-Z]+)\s+([a-zA-Z]+)$

我认为您正在寻找这个。只需抓住组来满足您的需求。参见演示。

http://regex101.com/r/hQ1rP0/6

我认为这个也可以工作,而且比你的短一点:

([A-Z][a-z]*)(?:,\s*)?

演示

或者你可以使用这个正则表达式来使用 split:

(,?\s+)
import re
def rearrange_name(name):
  result = re.search(r"^([\w \.-]*), ([\w \.-]*)$", name)  #Included extra characters i.e. .- to be captured in our groups in the event they are found.
  #result = re.search(r"^([\w .-]*), ([\w .-]*)$", name)  #seems to be also working without escaping the period
  if result == None:
    return name
  return "{} {}".format(result[2], result[1])

name=rearrange_name("Raila, Odinga M.")
print(name)`enter code here`
import re

def rearrange_name(name):
    result = re.search(r"^([\w \.-]*), ([\w \.-]*)$", name)
    if result == None:
        return name
    return "{} {}".format(result[2], result[1])

name = rearrange_name("Erick, Bett K.")
print(name)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM