python中的字符串匹配

python中的字符串匹配,python,Python,有四个文件,a.txt,b.txt,c.txt,d.txt 每个文件只有一列数据,其中包括商店/商场/餐厅等的名称。实际上,它们只是名称 我需要一个程序,可以将a.txt中的名称与其他三个文件中的名称进行匹配(b.txt,c.txt,d.txt)。通过匹配,我们的意思是,如果程序包含其他三个文件中的任何一个文件中可用的名称,那么它应该能够将a.txt中的一行标记为匹配。匹配需要智能化,也就是说,如果某个文件有餐厅,而另一个文件没有,那么它仍然应该匹配。因此,我们需要想出一些启发式方法来进行匹配

有四个文件,
a.txt
b.txt
c.txt
d.txt

每个文件只有一列数据,其中包括商店/商场/餐厅等的名称。实际上,它们只是名称

我需要一个程序,可以将
a.txt
中的名称与其他三个文件中的名称进行匹配(
b.txt
c.txt
d.txt
)。通过匹配,我们的意思是,如果程序包含其他三个文件中的任何一个文件中可用的名称,那么它应该能够将
a.txt
中的一行标记为匹配。匹配需要智能化,也就是说,如果某个文件有餐厅,而另一个文件没有,那么它仍然应该匹配。因此,我们需要想出一些启发式方法来进行匹配

我想要完美的匹配,例如,如果
a.txt
有以下内容之一

Ivan餐厅-新加坡Bukit Timah路
Ivan餐厅-新加坡Bukit Timah路12345号
Ivan餐厅-Bukit Timah路,12345
Ivan餐厅-12345,新加坡
新加坡Bukit Timah路Ivan餐厅
新加坡布吉提玛路12345号伊万餐厅
Ivan餐厅Bukit Timah路12345号
新加坡12345伊万餐厅
Ivan餐厅(新加坡Bukit Timah路)
Ivan餐厅(新加坡Bukit Timah路12345号)
伊万餐厅(Bukit Timah路12345号)
伊万餐厅(12345,新加坡)
或“Ivan餐厅”的任何此类变体 并且
b.txt
c.txt
d.txt
具有以下任一特征

伊万 伊万餐厅 那么, 只有完整的伊万餐厅应该匹配。但是,如果在
b.txt
c.txt
d.txt
中没有“Ivan restaurant”,但只有Ivan在那里,那么您可以从
a.txt
中去掉像restaurant这样的常用词,然后尝试匹配

我希望你能明白。类似的方法适用于商店、建筑物、商场等。这就是我所说的启发式

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()
见: 供contextlib导入时参考

至于一个简短的解释,首先它读了b、c和d中的所有行。它将把它们放在一个集合中,这将基本上消除重复项。之后,它将逐行读取一个.txt文件,并将其与集合进行匹配。print语句上的条带用于删除任何尾随\n,但在匹配之前可能需要这样做


不管怎样,刚刚测试过,它似乎很有效。

Blubber的解决方案很好,但可能不满足您的以下标准

或“Ivan Restaurant”和b.txt或c.txt或d.txt的任何此类变体 有下列情况之一吗

伊万伊万餐厅

那么,只有完整的伊万餐厅应该匹配。但是如果有 在b.txt、c.txt或d.txt中没有“Ivan餐厅”,但只有Ivan是 出现在那里,然后你去掉常用词,比如餐馆 a、 然后尝试匹配

为了使Blubber的解决方案适合您,您可能更愿意使用。该算法试图尽其最大能力进行匹配。如果您觉得这对您不起作用,您可能想看看difflib是如何工作的。请注意,启发式匹配不是一件容易的事情。有些库可能是您想要尝试的。但对您有效的方法完全取决于您的可接受性标准和数据模式。我建议与这些图书馆合作,看看什么最适合你

只是为了扩展Blubber的解决方案以合并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])

如果我正确理解了您的描述,您可以用
b.txt
c.txt
d.txt
的所有单词构建一个
set()
,然后循环查看
a.txt
的单词,并检查它是否是该集合的一部分。如果你需要知道更多关于这个词的信息,那么你可以使用一个
映射图
,从这个词映射到相关的信息,例如这个词是否在
b.txt
中以及从哪一行。你能给我代码吗?@user1077645-这个网站是为了帮助你解决你编写的代码的问题。如果你想让某人从头开始为你编写一个解决方案,请尝试或使用其他无数类似服务中的一个。我已经用不同的方法尝试过,但没有找到合适的解决方案,这就是为什么。。