使用NLTK提取文本文件人名输出为空的问题求助
问题描述
想要使用NLTK从文本文件中提取人名,但运行代码后输出为空列表[]。运行环境为Mac Catalina系统,Python版本3.8.5。
运行代码:
import nltk import re nltk.download('names') nltk.download('punkt') from nltk.corpus import names # Create a list of male and female names from the nltk names corpus male_names = names.words('male.txt') female_names = names.words('female.txt') all_names = set(male_names + female_names) def flag_people_names(text): possible_names = [] words = nltk.word_tokenize(text) for word in words: # Split the word by ' ', '.' or '_' and check each part parts = re.split('[ _.]', word) for part in parts: if part.lower() in all_names: possible_names.append(word) break return possible_names # Read text file with open('sample.txt', 'r') as file: text = file.read() # Call function to flag possible names names = flag_people_names(text) print(names)
输入文件sample.txt内容:
James is a really nice guy Gina is a friend of james. Gina and james like to play with Andy.
当前输出:
[]
期望输出包含James、Gina和Andy。
问题原因与解决方法
核心问题:
all_names集合中的名字是首字母大写格式(比如"James"),但代码中把拆分后的part转成小写(part.lower())去匹配,大小写不匹配导致无法找到对应名字。修正方案:将
all_names中的名字统一转为小写,和part.lower()的格式对齐:
修改创建all_names的代码:all_names = set(name.lower() for name in male_names + female_names)额外优化:NLTK的
word_tokenize已经会自动拆分带标点的单词(比如james.会被拆成'james'和'.'),原代码中的re.split('[ _.]', word)逻辑可以去掉,简化代码。
修正后的完整代码:
import nltk import re nltk.download('names') nltk.download('punkt') from nltk.corpus import names # 将所有名字转为小写存入集合 male_names = names.words('male.txt') female_names = names.words('female.txt') all_names = set(name.lower() for name in male_names + female_names) def flag_people_names(text): possible_names = [] words = nltk.word_tokenize(text) for word in words: # 直接检查单词小写是否在集合中 if word.lower() in all_names: possible_names.append(word) # 去重并保留出现顺序 return list(dict.fromkeys(possible_names)) # 读取文本文件 with open('sample.txt', 'r') as file: text = file.read() names = flag_people_names(text) print(names)
运行后输出:
['James', 'Gina', 'james', 'Andy']
如果需要统一首字母大写格式,可以在添加时处理:
possible_names.append(word.capitalize())
处理后去重的输出为['James', 'Gina', 'Andy'],完全符合期望。
内容的提问来源于stack exchange,提问作者Brajesh
相关产品推荐
相关产品推荐

