Python提取CEO姓名要素:头衔提取及方案优化咨询
提取CEO信息字符串要素的优化方案
问题背景
刚接触Python,需要处理网页爬取的CEO联系信息字符串,拆分出称呼、头衔、姓、名要素。要素存在多种变化:可能无称呼、头衔数量不定(单个/多个)、名字可能有多个,但要素顺序固定且仅有一个姓。现有代码头衔提取逻辑存在问题,需修正并寻求更优实现。
原代码及测试样例:
# 测试字符串样例 ceo1 = "Herr Dr. Mustermann Max" # 称呼、头衔、姓、名 ceo2 = "Müller Monika" # 仅名、姓 ceo3 = "Frau Mustermann Iris Petra" # 称呼、姓、两个名 ceo4 = "Herr Mag. Dr. Schubert Franz Peter" # 称呼、两个头衔、姓、两个名 ceo5 = "Herr Dipl.-Ing. BA Mozart Wolfgang Amadeus" # 称呼、两个头衔(其中一个无末尾点)、姓、两个名 ceo = ceo2 # 提取称呼 salutation_list = ["Herr", "Frau"] salutation_test = bool(sum(map(lambda x: x in ceo, salutation_list))) if salutation_test is True: salutation = ceo[0:4] ceo_without_salutation = ceo[5:] else: salutation = "N/A" ceo_without_salutation = ceo # 提取头衔(此处存在问题) title_list = ["Dr.", "Mag. Dr.", "BA", "Dipl.-Ing."] title_test = bool(sum(map(lambda x: x in ceo_without_salutation, title_list))) if title_test is True: title = "titel" # 如何从列表中提取对应元素并从字符串中移除? ceo_without_title = "ceo_without_salutation - titel" else: title = "N/A" ceo_without_title = ceo_without_salutation name_list = ceo_without_title.split(" ") # 提取姓 lastname = name_list[0] # 提取名 del name_list[0] firstname = "".join(name_list)
原代码核心问题
- 称呼提取逻辑不严谨:用固定切片
ceo[0:4],对"Frau"(仅3字符)会提取错误,且未确保称呼是字符串的开头单词 - 头衔处理失效:仅判断头衔是否存在,无法提取多个连续头衔,也不能准确从原字符串中移除头衔部分
- 名字拼接错误:用
"".join(name_list)会把多个名字直接连在一起(如"Iris Petra"变成"IrisPetra")
优化实现方案
基于要素固定顺序**[称呼(可选)→头衔组(可选)→姓→名组]**,采用拆分单词列表的方式分步处理,逻辑清晰且适配所有场景:
# 配置预设的称呼和头衔集合 SALUTATIONS = {"Herr", "Frau"} TITLES = {"Dr.", "Mag.", "BA", "Dipl.-Ing."} def parse_ceo_info(ceo_str): # 先把字符串拆分为单词列表,方便逐个处理 word_list = ceo_str.split() salutation = "N/A" title_list = [] lastname = "" firstnames = [] # 1. 提取开头的称呼(如果存在) if word_list and word_list[0] in SALUTATIONS: salutation = word_list.pop(0) # 2. 提取连续的所有头衔(如果存在) while word_list and word_list[0] in TITLES: title_list.append(word_list.pop(0)) # 3. 拆分姓和名:剩余列表第一个是姓,其余都是名 if word_list: lastname = word_list.pop(0) firstnames = word_list # 整理成结构化结果返回 return { "salutation": salutation, "title": ", ".join(title_list) if title_list else "N/A", "lastname": lastname, "firstname": " ".join(firstnames) if firstnames else "N/A" } # 测试所有样例 test_cases = [ "Herr Dr. Mustermann Max", "Müller Monika", "Frau Mustermann Iris Petra", "Herr Mag. Dr. Schubert Franz Peter", "Herr Dipl.-Ing. BA Mozart Wolfgang Amadeus" ] for idx, case in enumerate(test_cases, 1): result = parse_ceo_info(case) print(f"=== 测试样例 {idx} ===") print(f"原始字符串: {case}") print(f"称呼: {result['salutation']}") print(f"头衔: {result['title']}") print(f"姓: {result['lastname']}") print(f"名: {result['firstname']}\n")
方案优势
- 鲁棒性强:通过单词列表逐个匹配,避免固定切片的错误,适配所有场景
- 扩展性好:新增称呼或头衔只需修改集合,无需调整核心逻辑
- 格式规范:多个头衔用逗号分隔,多个名字用空格分隔,符合常规格式
测试输出
=== 测试样例 1 === 原始字符串: Herr Dr. Mustermann Max 称呼: Herr 头衔: Dr. 姓: Mustermann 名: Max === 测试样例 2 === 原始字符串: Müller Monika 称呼: N/A 头衔: N/A 姓: Müller 名: Monika === 测试样例 3 === 原始字符串: Frau Mustermann Iris Petra 称呼: Frau 头衔: N/A 姓: Mustermann 名: Iris Petra === 测试样例 4 === 原始字符串: Herr Mag. Dr. Schubert Franz Peter 称呼: Herr 头衔: Mag., Dr. 姓: Schubert 名: Franz Peter === 测试样例 5 === 原始字符串: Herr Dipl.-Ing. BA Mozart Wolfgang Amadeus 称呼: Herr 头衔: Dipl.-Ing., BA 姓: Mozart 名: Wolfgang Amadeus
内容的提问来源于stack exchange,提问作者Peter Silie
相关产品推荐
相关产品推荐

