【问题标题】:How can I match partial strings / is there a better way?如何匹配部分字符串/有更好的方法吗?
【发布时间】:2013-09-23 18:11:55
【问题描述】:

我正在通过 Expedia API 提取酒店名称,并与另一家旅行服务提供商交叉引用结果。

我遇到的问题是,许多酒店名称在 Expedia API 上的显示与在其他提供商中显示的不同,我无法找到匹配它们的好方法。

我将两者的结果与房价一起存储在单独的字典中。因此,例如,Expedia 在立陶宛搜索维尔纽斯的结果可能如下所示:

expediadict = {'Ramada Hotel & Suites Vilnius': 120, 'Hotel Rinno': 100,
'Vilnius Comfort Hotel': 110}

但来自其他提供商的结果可能如下所示:

altproviderdict = {'Ramada Vilnius': 120, 'Rinno Hotel': 100, 
'Comfort Hotel LT': 110}

我唯一能想到的就是删除“Hotel”、“Vilnius”、“LT”和“Lithuania”的所有实例,然后测试 expediadict 键的一部分是否与 altprovderdict 键的一部分匹配。这看起来很混乱而且不是很 Pythonic,所以我想知道你们中是否有人有更清晰的想法?

【问题讨论】:

  • 你听说过正则表达式吗?也许看看re 模块。
  • @EdgarAroutiounian 我认为这根本不是解决这个问题的正确方法......
  • 你有一个更可能是通用和唯一的标识符吗?比如电话号码、街道地址、一些标准化的身份证号码等?您可以加入酒店名称以外的其他内容。
  • 正则表达式不会帮助这个特定的实例。 @Robᵩ 遗憾的是我无法访问 API,所以我正在抓取。我可以那样做,但是会很费力(而且我注意到经常连地址都不一样!)

标签: python string api dictionary


【解决方案1】:
>>> def simple_clean(word):
...     return word.lower().replace(" ","").replace("hotel","")
... 
>>> a = "Ramada Hotel & Suites Vilnius"
>>> b = "Hotel Ramada Suites Vilnous"
>>> a = simple_clean(a)
>>> b = simple_clean(b)
>>> a
'ramada&suitesvilnius'
>>> b
'ramadasuitesvilnous'
>>> import difflib
>>> difflib.SequenceMatcher(None,a,b).ratio()
0.9230769230769231
  1. 对单词进行清理和规范化:例如。删除 Hotel、The、Resort 等词 , 并转换为不带空格的小写等

  2. 然后使用像 leveinstein 这样的模糊字符串匹配算法,例如来自difflib 模块。

此方法非常原始,只是一个示例,您可以对其进行增强以满足您的需求以获得最佳结果。

【讨论】:

  • #1 很危险。考虑Hyatt Place 和伊利诺伊州沃伦维尔的凯悦酒店。他们的名字只是在“地方”和“房子”这两个可能无关紧要的词上有所不同。
  • 在这种情况下,它们都会收到相同的匹配分数,并且都会返回给用户?这似乎是相当不错的行为(假设他返回某种排序列表而不是单个条目)
  • @rob ,同意,但这取决于用例,用户可以选择不删除这些词。
  • 谢谢大家,我对模糊字符串匹配一无所知,这将完美地工作。存在一些危险,但我返回结果的方式会将这些风险限制在可接受的水平。这就是为什么我喜欢 SO...
【解决方案2】:

如果您只想在单词以相同顺序出现时匹配名称,您可能希望使用一些最长的公共子序列算法,就像在 diff 工具中使用的那样。但用词代替字符或行。

如果顺序不重要,那就更简单了:把名字的所有单词放在一个这样的集合中:

set(name.split())

为了匹配两个名称,测试这两个集合的intersection 的大小。或者测试symmetric_difference是否只包含不重要的词。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-15
    • 2019-11-05
    • 2019-10-18
    • 2013-12-15
    • 2017-05-04
    • 1970-01-01
    • 2017-07-02
    相关资源
    最近更新 更多