2011-12-18 84 views
-2

有四個文件,a.txtb.txt,c.txt,d.txtpython中的字符串匹配

每個文件只有一列數據,其中包含商店/商場/餐館等的名稱。實際上,它們只是名稱。

我需要一個程序,可以將a.txt中的名稱與其他三個文件(b.txt,c.txt,d.txt)中的名稱進行匹配。通過匹配,我們的意思是程序應該能夠將a.txt中的一行標記爲匹配,前提是它包含三個其他文件中任何一個文件中可用的名稱。這些比賽需要智能化,即如果某個文件有餐廳,而另一個文件則不應該匹配。所以我們需要提出一些啓發式的方法來做一個很好的匹配。

我想要完美的匹配例如如果a.txt具有以下

Ivan Restaurant - Bukit Timah Road, Singapore 
Ivan Restaurant - Bukit Timah Road, 12345 Singapore 
Ivan Restaurant - Bukit Timah Road, 12345 
Ivan Restaurant - 12345, Singapore 
Ivan Restaurant Bukit Timah Road, Singapore 
Ivan Restaurant Bukit Timah Road, 12345 Singapore 
Ivan Restaurant Bukit Timah Road, 12345 
Ivan Restaurant 12345, Singapore 
Ivan Restaurant (Bukit Timah Road, Singapore) 
Ivan Restaurant (Bukit Timah Road, 12345 Singapore) 
Ivan Restaurant (Bukit Timah Road, 12345) 
Ivan Restaurant (12345, Singapore) 

或「伊萬餐廳」 和b.txtc.txtd.txt任何這樣的變化有任何以下

Ivan 
Ivan restaurant 

然後, 只有完整伊萬餐廳之一應該匹配。但是,如果b.txtc.txtd.txt中沒有「Ivan餐廳」,但只有Ivan存在,那麼您會從a.txt中刪除像餐廳這樣的常用詞,然後嘗試匹配。

我希望你明白。類似的商店,建築物,商場等。這就是我的啓發式意思。

+0

如果我理解你的描述正確你可以建立一個'設置()'用b.txt'的'所有的話,'c.txt' ,和'd.txt',然後遍歷'a.txt'的單詞並檢查它是否屬於這個集合的一部分。如果您需要了解有關該單詞的更多信息,則可以使用「地圖」,該地圖從單詞映射到相關信息,例如,無論這個詞是在「b.txt」還是來自哪一行。 – 2011-12-18 08:02:53

+0

你能給我這個代碼嗎? – Anoop 2011-12-18 08:21:34

+2

@ user1077645 - 此網站用於解決您編寫的代碼時遇到的問題。如果您希望有人爲您從頭開始編寫解決方案,請嘗試[Elance](https://www.elance.com/)或[vWorker](http://www.vworker.com/)或其中一種其他此類服務。 – Blair 2011-12-18 09:20:00

回答

1

巴波的解決方案是優秀的,但可能無法滿足您的下列標準

或「伊萬餐廳」和b.txt或c.txt任何這樣的變化或d.txt 具有以下任何

伊萬伊凡餐廳

然後,只有完整的伊凡餐廳應該匹配。但是,如果 在b.txt或c.txt或d.txt中不是「Ivan餐廳」,但是隻有Ivan是 ,那麼您可以從 a.txt中刪除像餐廳這樣的常用詞,然後嘗試匹配。

爲了讓鯨脂的解決方案爲您工作,您可能更喜歡使用difflib.get_close_matches。該算法試圖與其能力最好地匹配。如果你覺得這些東西不適合你,你可能想看看difflib是如何工作的。請注意,啓發式匹配不是一件容易的事情。您可能想要嘗試使用類似Levenshtein的庫。但是那些能爲你工作的人完全取決於你的可接受性標準和數據模式。我建議與這些庫一起工作,看看最適合你的是什麼。

只是爲了擴大鯨脂的解決方案納入difflib

import contextlib,difflib 

with contextlib.nested(open('b.txt', 'r'), open('c.txt', 'r'), open('d.txt', 'r')) as (b_fp, c_fp, d_fp): 
data = set(b_fp.readlines() + 
      c_fp.readlines() + 
      d_fp.readlines()) 

with open('a.txt', 'r') as fp: 
    for line in fp: 
     #if line in data: 
     match = difflib.get_close_matches(line,data) 
     if len(match) > 0: 
      #print "Matched %s" % line.strip() 
      print "({0}) matches with ({1})".format(line.strip(),match[0]) 
+0

非常感謝你Abhijit。 – Anoop 2011-12-18 11:12:17

3
import contextlib 

with contextlib.nested(open('b.txt', 'r'), open('c.txt', 'r'), open('d.txt', 'r')) as (b_fp, c_fp, d_fp): 
    data = set(b_fp.readlines() + 
       c_fp.readlines() + 
       d_fp.readlines()) 

with open('a.txt', 'r') as fp: 
    for line in fp: 
     if line in data: 
      print "Matched %s" % line.strip() 

參見: Multiple variables in Python 'with' statement有關contextlib進口參考。

至於一個簡短的解釋,首先它讀取b,c和d中的所有行。它會把它們放在一個集合中,這將基本消除重複。之後,它將逐行讀取a.txt並將其與集合進行匹配。打印語句上的那個條被用來去除任何結尾的\ n,但是在匹配前你可能想要這樣做。

無論如何,只是測試它,它似乎工作。