2014-09-22 107 views
1

使用python,从给定的字符串中提取常用短语或单词的最有效方法是什么?在字符串中查找匹配的短语和单词python

例如,

string1="once upon a time there was a very large giant called Jack" 
string2="a very long time ago was a very brave young man called Jack" 

将返回:

["a","time","there","was a very","called Jack"] 

一个会如何在有效地这样做(在我来说,我需要做的这几千年1000字的文件) ?

+3

我认为这里不需要正则表达式。 – 2014-09-22 15:23:02

+0

效率取决于你问的对象,因开发者的不同而不同。但就你而言,我想说在列表中混合使用单个单词和短语不会很有效。也许将每个单词存储到数据库中(或者创建自己的数据类型)并跟踪每个单词前后的内容...对您而言可能有效或不可能有效。 – 2014-09-22 15:30:02

回答

2

你可以每个字符串split,然后intersectset s。

string1="once upon a time there was a very large giant called Jack" 
string2="a very long time ago was a very brave young man called Jack" 
set(string1.split()).intersection(set(string2.split())) 

结果

set(['a', 'very', 'Jack', 'time', 'was', 'called']) 

注意这仅匹配单个的单词。你必须更具体地说明你会认为什么是“短语”。最长的连续匹配子字符串?这可能会变得更加复杂。

+0

我认为“最长的连续匹配子字符串”符合我的意思。 – user2592835 2014-09-22 15:50:59

+0

只需要注意''set.intersection'需要一个任意的迭代,所以只需使用'string2.split()'不需要明确的'set'调用 – 2014-09-22 15:54:12

+0

@JonClements我不知道这一点,谢谢你的提示! – CoryKramer 2014-09-22 15:55:10

1

在自然语言处理中,通常使用n-grams从句子中提取常见模式和序列。 在Python中,你可以使用优秀的NLTK模块。

要计算和查找最常见的,可以使用collections.Counter

下面是2-克例如:

from nltk.util import ngrams 
from collections import Counter 
from itertools import chain 

string1="once upon a time there was a very large giant called Jack" 
string2="a very long time ago was a very brave young man called Jack" 

n = 2 
ngrams1= ngrams(string1.split(" "), n) 
ngrams2= ngrams(string2.split(" "), n) 

counter= Counter(chain(ngrams1,ngrams2))  #count occurrences of each n-gram 
print [k[0] for k,v in counter.items() if v>1] #print all ngrams that come up more than once 

输出:

[('called', 'Jack'), ('was', 'a'), ('a', 'very')] 

输出与n=3

[('was', 'a', 'very')] 

输出与n=1(无元组):

['Jack', 'a', 'was', 'time', 'called', 'very'] 
1

这是一个经典的动态规划问题。所有你需要做的是为string1建立一个后缀树,用单词而不是字母(这是通常的表述)。这是一个illustrative example of a suffix tree

  1. 将树中的所有节点标记为s1
  2. 逐个插入所有后缀string2
  3. 步骤2中后缀所经过的所有节点标记为s2
  4. 在步骤2中创建的任何新节点也标记为s2
  5. 在最终的树中,标记为s1s2的每个节点的路径标签是常见的子字符串。

该算法在this lecture note中简洁地解释。

对于长度nm的两个字符串,后缀树建设需要O(max(n,m)),和所有匹配的子串(在你的情况,词或短语)可以在O(#matches)进行搜索。

相关问题