2014-09-22 106 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)進行搜索。

相關問題