首页 > 解决方案 > 如何使用 Python 中的正则表达式在单个字符串中分隔姓氏(大写)和名字(小写)?

问题描述

我正在做这个练习:

在这种情况下,姓氏用大写字母(大写)书写,并放在名字之前。

姓氏可以包含多个名称,并且可以用空格或连字符 (-) 分隔。姓氏可以包含小写介词(Di、Mac)。

有时名字和姓氏可以不带空格出现。

一个人可以有多个名字。

我尝试将这些字符串分成几组。=> 第一组姓氏(大写)。第二组名称(小写)。

测试输入:

DiCAPRIO Leonardo Wilhelm

MacGYVER Angus

ANDERSON Richard Dean

ZETA-JONES Catherine

BONHAM CARTER Helena

DOUGLASMichael

输出(它应该看起来如何):

["DiCAPRIO"], ["Leonardo Wilhelm"]

["MacGYVER"], ["Angus"]

["ANDERSON"], ["Richard Dean"]

["ZETA-JONES"], ["Catherine"]

["BONHAM CARTER"], ["Helena"]

["DOUGLAS"], ["Michael"]

我有一个正则表达式:

([A-Z]{2,}\s?\-?[A-Z]{2,}|[A-Z]{2,})

(此正则表达式适用于https://regex101.com

我使用该功能re.findall()

在 Python 3.x 中:

for author in arrayAuthors:
    print(re.findall(r'([A-Z]{2,}\s?\-?[A-Z]{2,}|[A-Z]{2,})', author))

在 Python 脚本中,它只捕获一个由两个名字组成的姓氏和一个带有连字符的姓氏。

["ZETA-JONES"], ["Catherine"]

["BONHAM CARTER"], ["Helena"]

其他名称返回不分:

["DiCAPRIO Leonardo Wilhelm"]

["MacGYVER Angus"]

["ANDERSON Richard Dean"]

["DOUGLASMichael"]

标签: pythonregex

解决方案


对于这个相当复杂的例子,我会选择正则表达式结合itertools.groupby

import re
from itertools import groupby


lst = [
    'DiCAPRIO Leonardo Wilhelm',
    'MacGYVER Angus',
    'ANDERSON Richard Dean',
    'ZETA-JONES Catherine',
    'BONHAM CARTER Helena',
    'DOUGLASMichael'
]

for v in lst:
    l = re.sub(r'([A-Z])([A-Z][a-z]+)$', r'\1 \2', v).split()
    out = [' '.join(g) for _, g in groupby(l, lambda k: bool(re.search(r'[a-z]$', k)))]
    print(out)

印刷:

['DiCAPRIO', 'Leonardo Wilhelm']
['MacGYVER', 'Angus']
['ANDERSON', 'Richard Dean']
['ZETA-JONES', 'Catherine']
['BONHAM CARTER', 'Helena']
['DOUGLAS', 'Michael']

推荐阅读