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

时间:2011-10-31 22:23:15

标签: 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 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()搜索任何名称列表是否为文本。

简单的方法是使用“in”运算符检查名称是否在列表中,但列表中有5,000个项目,因此效率不高。我可以将文本拆分为单词并检查单词是否为in列表,但如果您有多个单词匹配则不起作用。在这种情况下,第7行将失败。

4 个答案:

答案 0 :(得分:2)

名称设置为set并使用in-operator进行快速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'

答案 1 :(得分:2)

使用所有替代方法构建正则表达式。通过这种方式,您无需担心以某种方式事先从短语中删除名称。

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')

答案 2 :(得分:1)

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

答案 3 :(得分:1)

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

您的代码完全相同,第2行添加了此代码:

names = set(names)

in操作现在可以更快地运行。