如何用Python及其库提取段落中带缩写的姓名?
我正在处理项目中的姓名提取任务,从Word文档提取的段落里,需要识别带缩写的完整姓名。段落格式有这些特点:
- 句首以
Sri./SRI./Smt./SMT.开头,后面可能有空格或无空格 - 姓名中包含缩写(如
M. S. ANANTHKRISHNA、GANGA A.K、SANTHOSH BHAT.N.C) - 姓名后会出现
S/o/D/o/W/o/C/o这类标识,或者直接跟年龄信息
之前尝试过正则匹配、NLTK Stanford NER、SpaCy的PROPN标注,都没能正确识别带缩写的姓名,现有代码的正则和字符串拆分方案效果不佳,求可行的Python实现。
示例段落:
Sri. SHASHANK KUMAR, S/o.Sri.Rajat Kumar, aged about 45 years, residing at ADDRESS Hereinafter called as the VENDOR.
Sri. M. S. ANANTHKRISHNA ,aged about 46 years, S/o. Sri. M.Neelakant residing at ADDRESSS. Hereinafter called the SECOND PARTY (PURCHASER).
Smt. GANGA A.K, D/o. Sri. Mukesh, aged about 31 years, residing at ADDRESS Hereinafter called the PURCHASER.
SRI.SANTHOSH BHAT.N.C S/o.Sri. Chikkabasappa, aged about 29 years, residing at ADDRESS Hereinafter called the PURCHASER.
现有相关代码:
def get_vendor_purchaser_details(df_hierchical_clustered_output): df_vendor_purchaser_details = df_hierchical_clustered_output[df_hierchical_clustered_output['k_means_labels_primary'] == 4][["id", "filename", "para_text"]] vendor_detail_list = [] for index, row in df_vendor_purchaser_details.iterrows(): vendor_detail = {} vendor_detail["id"] = row["id"] vendor_detail["para_text"] = row["para_text"] vendor_detail["name"] = get_vendor_name(row) vendor_detail_list.append(vendor_detail) print(vendor_detail["name"]) def get_vendor_name(entry): para_text = entry["para_text"] # 之前尝试的正则和拆分方案均无效 # name_pattern = r'Sri. [A-Z\s]*|SRI.[A-Z\s]*|Smt. [A-z\s]*|SMT.[A-Z\s]*|SRI. [A-z\s]*|SMT. [A-Z\s]*' # vendor_name = re.findall(name_pattern,para_text) # ---------------------------------------------------- # if "S/o" in para_text: # vendor_name = para_text.split("S/o")[0] # elif "D/o" in para_text: # vendor_name = para_text.split("D/o")[0] # elif "C/o" in para_text: # vendor_name = para_text.split("C/o")[0] # elif "W/o" in para_text: # vendor_name = para_text.split("W/o")[0] # else: # vendor_name = "" # return vendor_name
针对你的段落格式,设计专门的正则表达式来匹配带缩写的姓名,核心思路:
- 匹配开头的敬称(
Sri./SRI./Smt./SMT.),处理后面有无空格的情况 - 匹配姓名部分:允许大写字母、点号、空格,直到遇到
S/o/D/o/W/o/C/o、逗号、年龄标识(aged)这类终止符 - 清理匹配结果中的多余空格和标点
改进后的代码实现
import re def get_vendor_name(entry): para_text = entry["para_text"] # 正则模式:匹配敬称开头,然后匹配姓名直到终止符 name_pattern = r'(Sri\.|SRI\.|Smt\.|SMT\.)\s?([A-Z\s\.]+?)(?=\s*(S/o|D/o|W/o|C/o|aged|,))' matches = re.search(name_pattern, para_text, re.IGNORECASE) if matches: # 提取姓名部分,清理多余空格和末尾的点/空格 full_name = matches.group(2).strip().rstrip('.') # 合并连续空格 full_name = re.sub(r'\s+', ' ', full_name) return full_name return "" # 测试示例 test_paragraphs = [ "Sri. SHASHANK KUMAR, S/o.Sri.Rajat Kumar, aged about 45 years, residing at ADDRESS Hereinafter called as the VENDOR.", "Sri. M. S. ANANTHKRISHNA ,aged about 46 years, S/o. Sri. M.Neelakant residing at ADDRESSS. Hereinafter called the SECOND PARTY (PURCHASER).", "Smt. GANGA A.K, D/o. Sri. Mukesh, aged about 31 years, residing at ADDRESS Hereinafter called the PURCHASER.", "SRI.SANTHOSH BHAT.N.C S/o.Sri. Chikkabasappa, aged about 29 years, residing at ADDRESS Hereinafter called the PURCHASER." ] for para in test_paragraphs: print(get_vendor_name({"para_text": para}))
测试结果
运行上述测试代码会输出:
SHASHANK KUMAR M. S. ANANTHKRISHNA GANGA A.K SANTHOSH BHAT.N.C
正则说明
(Sri\.|SRI\.|Smt\.|SMT\.):匹配开头的敬称,转义点号避免匹配任意字符\s?:匹配敬称后可选的空格(处理有空格或无空格的情况)([A-Z\s\.]+?):非贪婪匹配姓名部分,允许大写字母、空格、点号(支持缩写)(?=\s*(S/o|D/o|W/o|C/o|aged|,)):正向预查终止符,确保匹配到姓名结束的位置,不包含终止符本身- 后续的
strip()、rstrip('.')和re.sub(r'\s+', ' ', full_name)用于清理多余的空格和末尾的点号,保证姓名格式整洁
内容的提问来源于stack exchange,提问作者Shashank Shandilya

