2011-12-18 79 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,但是在匹配前你可能想要这样做。

无论如何,只是测试它,它似乎工作。