什么是在字符串(Python)中匹配单词的有效方法?

什么是在字符串(Python)中匹配单词的有效方法?,python,Python,例如: 1. names = ['James John', 'Robert David', 'Paul' ... the list has 5K items] 2. 3. text1 = 'I saw James today' 4. text2 = 'I saw James John today' 5. text3 = 'I met Paul' 6. 7. is_name_in_text(text1,names) # this returns false 'James' in not i

例如:

1. names = ['James John', 'Robert David', 'Paul' ... the list has 5K items]
2. 
3. text1 = 'I saw James today'
4. text2 = 'I saw James John today'
5. text3 = 'I met Paul'
6. 
7. is_name_in_text(text1,names)   # this returns false 'James' in not in list
8. is_name_in_text(text2,names)   # this returns 'James John'
9. is_name_in_text(text3,names)   # this return 'Paul'
is_name_in_text()搜索是否有任何名称列表在文本中

简单的方法是使用中的“
”操作符检查名称是否在列表中,但列表有5000项,因此效率不高。我可以将文本拆分为单词,然后检查单词是否在列表中
,但如果有多个单词匹配,这将不起作用。在这种情况下,行号7将失败。

将名称转换为a,并使用in运算符进行快速O(1)查找

您可以使用正则表达式解析句子中可能的名称:

>>> import re
>>> findnames = re.compile(r'([A-Z]\w*(?:\s[A-Z]\w*)?)')
>>> def is_name_in_text(text, names):
        for possible_name in set(findnames.findall(text)):
            if possible_name in names:
                return possible_name
        return False

>>> names = set(['James John', 'Robert David', 'Paul'])
>>> is_name_in_text('I saw James today', names)
False
>>> is_name_in_text('I saw James John today', names)
'James John'
>>> is_name_in_text('I met Paul', names)
'Paul'

您可以使用Python,以便在使用in运算符时获得良好的性能。

如果您有一种从短语中提取名称的机制,并且不需要担心部分匹配(全名将始终在字符串中),则可以使用集合而不是列表

您的代码完全相同,在第2行添加了以下内容:

names = set(names)

中的
操作现在将运行得更快。

使用所有可选项构建正则表达式。这样你就不必担心事先从短语中提取出名字

import re
names_re = re.compile(r'\b' +
                      r'\b|\b'.join(re.escape(name) for name in names) +
                      r'\b')

print names_re.search('I saw James today')

你已经有了从短语中提取名字的机制了吗?是的,我可以改变。它也可以在字典里<代码>[“詹姆斯·约翰”:“詹姆斯·约翰”]
很好地提出了这个问题。显示测试数据做得很好。我对从短语中提取名称的机制感兴趣。是的,一旦你有了它,你就可以使用
集合了,但是你如何有效地使用它呢?你如何使用
中的
来搜索
集合中的任何一个(['James John','Robert David',…]))
“我今天看到了James John”
中,编辑了答案以显示用于捕获文本输入中姓名的正则表达式。下面是一个反例句子:
“对于John James,这不起作用。”
???“约翰·詹姆斯”不在样本数据中。看起来你把名字和姓氏调换了。对不起
“For James John”
:关键是您的regexp匹配的是
For James
John
,而不是
James John
。这是一个很好的答案,尽管它确实会导致一个具有5000多个名称的相当大的regex:-)这是一个问题吗?编译regexp需要一些时间(我有15000多个名字的时间),但是搜索几乎是即时的。