使用python正则表达式从字符串中提取名称

2024-06-01 08:38:52 发布

您现在位置:Python中文网/ 问答频道 /正文

我一直在尝试从字符串中提取名称,但似乎没有成功。在

代码如下:

string = "555-1239Moe Szyslak(636) 555-0113Burns, C. Montgomery555 -6542Rev. Timothy Lovejoy555 8904Ned Flanders636-555-3226Simpson, Homer5553642Dr. Julius Hibbert"
regex = re.compile(r'([A-Z][a-z]+(?: [A-Z][a-z]\.)? [A-Z][a-z]+)')
print(regex.findall(string))

这是我得到的输出。['Moe Szyslak', 'Timothy Lovejoy', 'Ned Flanders', 'Julius Hibbert']


Tags: 字符串代码re名称stringregexcompilejulius
3条回答

以下是一种使用零宽度lookaround来隔离每个名称的方法:

string = "555-1239Moe Szyslak(636) 555-0113Burns, C. Montgomery555 -6542Rev. Timothy Lovejoy555 8904Ned Flanders636-555-3226Simpson, Homer5553642Dr. Julius Hibbert"
result = re.findall(r'(?:(?<=^)|(?<=[^A-Za-z.,]))[A-Za-z.,]+(?: [A-Za-z.,]+)*(?:(?=[^A-Za-z.,])|(?=$))', string)

print(result)

['Moe Szyslak', 'Burns, C. Montgomery', 'Rev. Timothy Lovejoy', 'Ned Flanders',
 'Simpson, Homer', 'Dr. Julius Hibbert']

实际匹配的模式是:

^{pr2}$

这表示匹配任何大写或小写字母、点或句点,后跟空格和一个或多个相同字符,零次或多次。在

此外,我们在该模式的左右两侧使用以下环视:

(?:(?<=^)|(?<=[^A-Za-z.,]))
Lookbehind and assert either the start of the string, or a non matching character
(?:(?=[^A-Za-z.,])|(?=$))
Lookahead and asser either the end of the string or a non matching character

众所周知,即使用英语也很难提取人名。以下正则表达式解决了您的特定问题,但在其他输入上可能会失败(例如,它不捕获带有破折号的名称):

re.findall(r"[A-Z][a-z]+,?\s+(?:[A-Z][a-z]*\.?\s*)?[A-Z][a-z]+", string)
#['Moe Szyslak', 'Burns, C. Montgomery', 'Timothy Lovejoy', 
# 'Ned Flanders', 'Simpson, Homer', 'Julius Hibbert']

以及标题:

^{pr2}$

作为一个补充说明,没有必要编译regex,除非您计划重用它。在

花哨的正则表达式需要时间来编写,而且很难维护。在这种情况下,我倾向于保持简单:

re.findall(r"[^()0-9-]+", string)

输出:

['Moe Szyslak', ' ', 'Burns, C. Montgomery', ' ', 'Rev. Timothy Lovejoy', ' ', 'Ned Flanders', 'Simpson, Homer', 'Dr. Julius Hibbert']

如果空白是个问题,我会过滤list(filter(str.strip,list))

相关问题 更多 >