2011-05-24 55 views
2

我有一個python列表,其中包含約700個術語,我想用它作爲Django中某些數據庫條目的元數據。我想將條目列表中的條款與條目描述相匹配,以查看是否有任何條款匹配,但存在一些問題。我的第一個問題是列表中有一些包含其他列表條目的單詞的多字詞。一個例子是:最好的方法來匹配大型列表與python中的字符串

Intrusion 
Intrusion Detection 

我已經不是很遠與re.findall因爲它會在上面的例子中同時匹配入侵和入侵檢測得到。我只想匹配入侵檢測而不是入侵。

有沒有更好的方法來做這種匹配?我想也許可能是嘗試NLTK,但它看起來並不像它可以幫助這種類型的匹配。

編輯:

所以要加點更清晰,我的700項條款,如防火牆或入侵檢測列表。我想嘗試將列表中的這些詞語與我已經存儲在數據庫中的描述進行匹配,以查看是否有任何匹配,並且我將在元數據中使用這些詞語。所以,如果我有以下字符串:

There are many types of intrusion detection devices in production today. 

,如果我有以下術語列表:

Intrusion 
Intrusion Detection 

我想匹配「入侵檢測」,而不是「入侵」。真的,我也希望能夠匹配單數/複數實例,但我可能會超越自己。所有這些背後的想法是把所有的比賽都放在一個列表中,然後處理它們。

+1

你能提供一些示例數據?這個問題有點不清楚 – Daenyth 2011-05-24 00:38:22

回答

2

如果您需要更多的靈活性,以匹配條目描述,你可以結合nltkre

from nltk.stem import PorterStemmer 
import re 

假設你有相同的不同描述事件即。 重寫系統。您可以使用nltk.stem捕捉重寫,重寫,重寫,單數和複數形式等

master_list = [ 
    'There are many types of intrusion detection devices in production today.', 
    'The CTO approved a rewrite of the system', 
    'The CTO is about to approve a complete rewrite of the system', 
    'The CTO approved a rewriting', 
    'Breaching of Firewalls' 
] 

terms = [ 
    'Intrusion Detection', 
    'Approved rewrite', 
    'Firewall' 
] 

stemmer = PorterStemmer() 

# for each term, split it into words (could be just one word) and stem each word 
stemmed_terms = ((stemmer.stem(word) for word in s.split()) for s in terms) 

# add 'match anything after it' expression to each of the stemmed words 
# join result into a pattern string 
regex_patterns = [''.join(stem + '.*' for stem in term) for term in stemmed_terms] 
print(regex_patterns) 
print('') 

for sentence in master_list: 
    match_obs = (re.search(pattern, sentence, flags=re.IGNORECASE) for pattern in regex_patterns) 
    matches = [m.group(0) for m in match_obs if m] 
    print(matches) 

輸出:

['Intrus.*Detect.*', 'Approv.*rewrit.*', 'Firewal.*'] 

['intrusion detection devices in production today.'] 
['approved a rewrite of the system'] 
['approve a complete rewrite of the system'] 
['approved a rewriting'] 
['Firewalls'] 

編輯:

要查看其中terms造成匹配:

for sentence in master_list: 
    # regex_patterns maps directly onto terms (strictly speaking it's one-to-one and onto) 
    for term, pattern in zip(terms, regex_patterns): 
     if re.search(pattern, sentence, flags=re.IGNORECASE): 
      # process term (put it in the db) 
      print('TERM: {0} FOUND IN: {1}'.format(term, sentence)) 

輸出:

TERM: Intrusion Detection FOUND IN: There are many types of intrusion detection devices in production today. 
TERM: Approved rewrite FOUND IN: The CTO approved a rewrite of the system 
TERM: Approved rewrite FOUND IN: The CTO is about to approve a complete rewrite of the system 
TERM: Approved rewrite FOUND IN: The CTO approved a rewriting 
TERM: Firewall FOUND IN: Breaching of Firewalls 
+0

這個解決方案看起來不錯,但是有沒有一種方法可以確定'條款'引起匹配的條目?這是我試圖在數據庫中插入的信息。 – ajt 2011-05-24 12:14:36

+1

@ajt使用'regex_patterns'由'terms'構建的事實,如果有匹配過程'term',請參閱編輯 – 2011-05-24 14:17:47

+0

太棒了。謝謝。 – ajt 2011-05-24 15:02:24

0

這個問題還不清楚,但根據我的理解,你有一個主要術語表。每行說一個術語。接下來,您將看到一組測試數據,其中一些測試數據將位於主列表中,另一些則不會。您想查看測試數據是否在主列表中,以及它是否執行任務。

假設你的主列表看起來像這樣

入侵檢測
防火牆
FooBar的

和您的測試數據看起來這

入侵
入侵檢測
FOO
酒吧

這個簡單的腳本應該引領你在正確的方向

#!/usr/bin/env python 

import sys 

def main(): 
    '''useage tester.py masterList testList''' 


    #open files 
    masterListFile = open(sys.argv[1], 'r') 
    testListFile = open(sys.argv[2], 'r') 

    #bulid master list 
    # .strip() off '\n' new line 
    # set to lower case. Intrusion != intrusion, but should. 
    masterList = [ line.strip().lower() for line in masterListFile ] 
    #run test 
    for line in testListFile: 
    term = line.strip().lower() 
    if term in masterList: 
     print term, "in master list!" 
     #perhaps grab your metadata using a like %% 
    else: 
     print "OH NO!", term, "not found!" 

    #close files 
    masterListFile.close() 
    testListFile.close() 

if __name__ == '__main__': 
    main() 

樣本輸出

噢,不!沒有發現入侵!
主列表中的入侵檢測!
OH NO! foo找不到!
OH NO!酒吧找不到!

還有其他幾種方法可以做到這一點,但這應該指向正確的方向。如果你的名單很大(700真的不是那麼大)考慮使用字典,我覺得他們更快。特別是如果你計劃查詢數據庫。也許是字典結構可能看起來像{項:關於期限的信息}

相關問題