2017-02-13 63 views
1

我正在使用NLTK分塊,我想捕獲匹配我的規則的字符串。例如NLTK:如何訪問分塊字符串

這裏是我的輸入

The stocks show 67% rise, last year it was 12% fall

我想捕捉

67% rise12% fall

詞性標註上面的句子表明

('The', 'DT'), ('stocks', 'NNS'), ('show', 'VBP'), ('67', 'CD'), ('%', 'NN'), ('rise', 'NN'), (',', ','), ('last', 'JJ'), ('year', 'NN'), ('it', 'PRP'), ('was', 'VBD'), ('12', 'CD'), ('%', 'NN'), ('fall', 'NN') 

現在,我想出了一個簡單的規則

Stat: {<CD><NN>(<NN>+|<VBN>|JJ)?}

效果很好,並且捕獲

('67', 'CD'), ('%', 'NN'), ('rise', 'NN') 

('12', 'CD'), ('%', 'NN'), ('fall', 'NN') 

現在,我想提取被抓獲的確切字符串。所以,我想

67% rise12% fall

我試圖

current=[] 
for word,tag in subtree.leaves(): 
    current.append(word) 
print ' '.join(current) 

,但我得到

67 % rise12 % fall

通知空間%和數字之間。這在邏輯上是正確的,但不是所需的輸出。我想要確切的字符串,因爲我想知道捕獲的字符串的開始和結束索引。

我該如何做到這一點?

+1

%_always_是否加入了數字,即您總是有'67%'而不是'67%'? – Chuck

+0

是的,絕對是 – AbtPst

+1

標記器不會跟蹤字符串中的標記的來源,所以任何解決方案都會有些破解。我肯定會解決這個級別的問題(將簡單標記與原始字符串相匹配),然後根據標記索引標識出您之後的塊。 – alexis

回答

1

(可怕地哈克) 對於示例字符串和標籤:

s = ('The', 'DT'), ('stocks', 'NNS'), ('show', 'VBP'), ('67', 'CD'), ('%', 'NN'), ('rise', 'NN'), (',', ','), ('last', 'JJ'), ('year', 'NN'), ('it', 'PRP'), ('was', 'VBD'), ('12', 'CD'), ('%', 'NN'), ('fall', 'NN') 
a = (('67', 'CD'), ('%', 'NN'), ('rise', 'NN')) 
c = 'The stocks show 67% rise, last year it was 12% fall' 

編輯:作爲一個列表理解:

>>>c[min((c.index(i[0]) for i in a)):max((c.index(i[0]) for i in a)) + [len(i[0]) for i in a][-1]] 
>>>'67% rise' 

發現你輸入的句子中出現的每個字的位置。記錄每個單詞的長度。

檢查您希望的詞類標籤在您的例句中的位置。 :

position=[] 
lengths=[] 

for wordtag in a: 
    print wordtag,c.index(i[0]),wordtag[0],len(wordtag[0]) 
    position.append(c.index(wordtag[0])) 
    lengths.append(len(wordtag[0])) 

> ('67', 'CD') 16 67 2 
> ('%', 'NN') 18 % 1 
> ('rise', 'NN') 20 rise 4 

print position 
print lengths 

> [16, 18, 20] 
> [2, 1, 4] 

切片根據所需的標籤的最小和最大位置的輸入句子(編輯刪除,如果爲是不必要的)。您可以添加lengths[-1]以添加單詞rise的長度。

valid = c[min(position):max(position) + lengths[-1]] 
print valid 

> [16, 18, 20] 
> [2, 1, 4] 

> 67% rise 

然後可以概括爲這樣的句子和語音標籤的一部分的任何名單。