2011-10-31 95 views
0

例子:匹配字符串(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行将失败。

+0

您是否已经有了一种将名称拉出短语的机制? –

+0

是的,我可以做出改变。它也可以在字典中。 '['詹姆斯约翰':'詹姆斯约翰']' – Sam

+1

恰好提出的问题。显示测试数据的好工作。 –

回答

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' 
+0

如何在''我今天看到詹姆斯约翰'中用'in'去搜索'set'(['James John','Robert David',...])''? –

+0

编辑答案以显示捕获文本输入中名称的正则表达式。 –

+0

下面是你的一个反例句:'“对于约翰·詹姆斯,这不起作用。”' –

1

您可以使用,而在操作使用Python的set,以获得良好的性能。

1

如果您有一种将名称拉出短语并且不必担心部分匹配(全名始终位于字符串中)的机制,则可以使用一组而不是一个列表。

你的代码是完全一样的,但增加了第2行:

names = set(names) 

in操作现在可以正常快得多。

1

使用所有替代方法构建正则表达式。这样你就不必担心事先将这些名字从这些短语中拉出来。

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

这是一个很好的答案,虽然它确实为5000+以上的相当大的正则表达式:-) –

+0

这是一个问题吗?编译正则表达式需要一些时间(我为15000+个名字获得了第二个),但搜索几乎是即时的。 –

相关问题