使用正则表达式提取带连字符的个人姓名的不同变体

时间:2019-03-21 12:13:02

标签: regex python-3.x

我需要在标题之后提取名称,但是我还需要包括带连字符的名称,这些名称可能会有不同的变化。 下面的脚本无法选择带连字符的名称。

    text = 'This is the text where Lord Lee-How and Sir Alex Smith are mentioned.\
     Dame Ane Paul-Law is mentioned too. And just Lady Ball.'
    names = re.compile(r'(Lord|Baroness|Lady|Baron|Dame|Sir) ([A-Z][a-z]+)[ ]?([A-Z][a-z]+)?')
    names_with_titles = list(set(peers.findall(text)))  
    print(names_with_titles)

当前输出为:

[('Lord', 'Lee', ''), ('Sir', 'Alex', 'Smith'), ('Dame', 'Ane', 'Paul'), ('Lady', 'Ball', '')]

所需的输出应为:

[('Lord', 'Lee-How', ''), ('Sir', 'Alex', 'Smith'), ('Dame', 'Ane', 'Paul-Law'), ('Lady', 'Ball', '')]

我设法用这种模式提取了带连字符的名字-

hyph_names = re.compile(r'(Lord|Baroness|Lady|Baron|Dame|Sir) ([A-Z]\w+(?=[\s\-][A-Z])(?:[\s\-][A-Z]\w+)+)')

但是我不知道如何将两者结合起来。感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

您可以在名称部分样式中添加一个(?:-[A-Z][a-z]+)?可选组:

(Lord|Baroness|Lady|Baron|Dame|Sir)\s+([A-Z][a-z]+(?:-[A-Z][a-z]+)?)(?:\s+([A-Z][a-z]+(?:-[A-Z][a-z]+)?))?

请参见regex demo

详细信息

  • (Lord|Baroness|Lady|Baron|Dame|Sir)-标题之一
  • \s+-一个或多个空格字符
  • ([A-Z][a-z]+(?:-[A-Z][a-z]+)?)-捕获组#1:
    • [A-Z][a-z]+-大写字母,后跟1+小写字母
    • (?:-[A-Z][a-z]+)?-一个可选的非捕获组,匹配连字符,然后是大写字母,后跟1+小写字母
  • (?:\s+([A-Z][a-z]+(?:-[A-Z][a-z]+)?))?-可选的非捕获组:
    • \s+-超过1个空格
    • ([A-Z][a-z]+(?:-[A-Z][a-z]+)?)-具有与组1相同模式的捕获组#2。

您可以像在python 3.7中那样构建它

title = r'(Lord|Baroness|Lady|Baron|Dame|Sir)'
name = r'([A-Z][a-z]+(?:-[A-Z][a-z]+)?)'
rx = rf'{title}\s+{name}(?:\s+{name})?'    

在旧版本中,

rx = r'{0}\s+{1}(?:\s+{1})?'.format(title, name)