2013-03-20 18 views
7

我想從包含使用python的給定子字符串的字符串中獲取句子。查找字符串中char/word的句子

我有權訪問字符串(學術摘要)和帶有開始和結束索引的高亮列表。例如:

{ 
    abstract: "...long abstract here..." 
    highlights: [ 
    { 
     concept: 'a word', 
     start: 1, 
     end: 10 
    } 
    { 
     concept: 'cancer', 
     start: 123, 
     end: 135 
    } 
    ] 
} 

我遍歷每個亮點,定位它在抽象的開始指數(結束並不重要,因爲我只需要得到一個句子中的位置),然後以某種方式需要確定索引發生的句子。

我能夠使用nltk.tonenize.sent_tokenize將摘要標記爲句子,但這樣做會導致索引位置無用。

我應該如何解決這個問題?我認爲正則表達式是一種選擇,但nltk標記器似乎是一種很好的方式,它不會使用它是一種恥辱。或者通過查找自上一句句號/感嘆號/問號?

+0

這看起來像JSON。 – squiguy 2013-03-20 17:20:02

+0

是的,我正在操作來自API端點的數據。 – Elise 2013-03-20 17:21:16

+0

它可能很昂貴,但你可以通過句子,並重新計算長度的句子索引,然後搜索該索引 – user1937198 2013-03-20 17:38:39

回答

6

你是對的,在這種情況下,NLTK tokenizer實際上就是你應該使用的,因爲它足夠強大,足以處理大部分所有句子的分隔,包括用「引語」結尾句子。您可以(從隨機生成paragraph)做這樣的事情:

開始,

from nltk.tokenize import sent_tokenize 

paragraph = "How does chickens harden over the acceptance? Chickens comprises coffee. Chickens crushes a popular vet next to the eater. Will chickens sweep beneath a project? Coffee funds chickens. Chickens abides against an ineffective drill." 
highlights = ["vet","funds"] 
sentencesWithHighlights = [] 

最直觀的方式:

for sentence in sent_tokenize(paragraph): 
    for highlight in highlights: 
     if highlight in sentence: 
      sentencesWithHighlights.append(sentence) 
      break 

但是,使用這種方法,我們實際上有什麼是有效的3x嵌套for循環。這是因爲我們首先檢查每個sentence,然後每個highlight,然後sentence中的每個子序列爲highlight

,因爲我們知道每個亮點的開始索引,我們可以得到更好的性能:

highlightIndices = [100,169] 
subtractFromIndex = 0 
for sentence in sent_tokenize(paragraph): 
    for index in highlightIndices: 
     if 0 < index - subtractFromIndex < len(sentence): 
      sentencesWithHighlights.append(sentence) 
      break 
    subtractFromIndex += len(sentence) 

在我們得到這兩種情況下:

sentencesWithHighlights = ['Chickens crushes a popular vet next to the eater.', 'Coffee funds chickens.'] 
+1

這正是我正在尋找,簡單易懂,謝謝! – Elise 2013-03-20 19:07:02

1

我假設你所有的句子這三個字符之一結尾:!?.

什麼遍歷亮點列表,創建一個正則表達式組:

(?:list|of|your highlights) 

然後匹配您的整個抽象反對這個正則表達式:

/(?:[\.!\?]|^)\s*([^\.!\?]*(?:list|of|your highlights)[^\.!\?]*?)(?=\s*[\.!\?])/ig 

這樣你會得到至少包含你的第一個subgrou中的一個亮點的句子(RegExr)。

0

另一種選擇(雖然這是很難說這將是多麼可靠,可變定義的文本),將文本分割成句子的列表,並測試對他們說:

re.split('(?<=\?|!|\.)\s{0,2}(?=[A-Z]|$)', text)