【问题标题】:How to write a fairly complicated python regular expression for addresses and place names?如何为地址和地名编写一个相当复杂的python正则表达式?
【发布时间】:2012-08-10 20:11:40
【问题描述】:

我正在尝试将一个营业地点名称和地址与另一个可能重复的营业地点名称和地址进行比较。问题是,姓名和地址通常是人工输入的,因此显然存在各种差异。

这里有一些例子:

圣。 vs. 街 vs. 街

圣。 14 vs. Ste 14 vs. Suite 14 vs. #14

NE 39th Ave. vs. 39th Ave. vs. 39th Avenue vs. NE 39th Avenue

还有更多是可能的......

我想在我的程序中编写一个正则表达式(使用 python)来比较将捕获这些细微差异的名称和地址。实际上,我经常看到看起来完全一样的地址,但对于少数不一样的地址,我不希望正则表达式完全拒绝它并说它们不一样。

地名有时也是如此。 (真实的)例子:

“埃尔多拉多”与“埃尔多拉多墨西哥餐厅”

“东亚特兰大咖啡店”与“乔的东亚特兰大咖啡店”

“乡村餐厅”与“爸爸村”

“DJR 清洁企业”与“DJR 清洁企业公司”

如果您对如何执行此操作或代码想法有任何建议,我将不胜感激,因为我现在只知道如何做简单的正则表达式。我以前从来没有遇到过这么大的问题...

谢谢。

【问题讨论】:

  • 你可以使用pyparsing来帮助解析街道信息
  • 这不是一个真正的 Python 问题
  • 这几乎肯定超出了正则表达式。您可以使用正则表达式来提取字符串的相关部分(例如,提取街道名称和地址编号),但您需要有其他逻辑来比较它们并确定它们是否“相同”。
  • 我不建议使用单个正则表达式来解决此类问题,否则您最终可能会遇到像 this 这样的怪物

标签: regex


【解决方案1】:

正如 cmets 中的每个人都提到的,这个问题不太适合单个正则表达式。我最近在同一领域做了很多工作,我首先要说的是,你永远无法做到 100% 完美。这是一个“尽可能好”的问题。

专注于地址比较组件,我发现的最佳策略如下:

  1. 将地址标记为单个单词(从而忽略奇怪的标点符号等)并重新加入字符串。

  2. 从最后开始,搜索国家或州(从预定义的列表中) - 如果找到,则删除并存储。我们从末尾开始搜索,因为地址的结尾似乎比开头更容易预测!

  3. 从最后开始,使用 (\d{4}) 搜索邮政编码或邮政编码,其中 4 是位数 - 如果找到则删除并存储。将 4 替换为您的目标国家/地区的数字或数字。

  4. 从最后开始,搜索郊区 - 如果找到则删除并存储。我们有一个预定义的哈希图/字典或郊区,这很有帮助。最好存储每个匹配项以供以后选择最佳匹配项(例如检查邮政/邮政编码匹配)。如果你有这些数据,也许你也可以从邮政编码中查找郊区。

  5. 最后是找到街道地址!很难,因为格式太多了:

    1. 我用它来提取 unit/shop/suite/site/factory/lot 组件:

      (unit|unt|un|u|shop|shp|suite|ste|se|site|factory|fy|lot|lt)s?(\s|\.)?(\w?\d+\w?)

    2. 我生成了一个序数正则表达式来提取级别/楼层:

      ((\w??\d+\w??|g|grnd|ground|lower|first|second|third|fourth|fifth|sixth|seventh|eighth|nineth|tenth|eleventh|twelth|1st|2st|3rd|4th|5th|6th|7th)(?:\s*|\.*|\s*)*(level|lvl|l|floor|flr|fl|f)

    3. 删除其他组件后,您通常只剩下类似于街道地址的东西。我用它来提取它:

      \d+(\s*-\s?\d*|\s*)?\D+(highway|freeway|alley|arcade|avenue|boulevard|bypass|chase|circle|circlet|circuit|circus|close|court|cove|crescent|drive|esplanade|fairway|garden|gardens|grove|lane|mall|mews|parade|parkway|place|plaza|promenade|quay|ridge|ridgeway|road|row|square|street|terrace|walk|way|Al|ar|ave|blvd|by|cc|ch|ci|cs|cct|cres|cr|cst|dip|dr|ed|ent|es|fry|fo|fmn|fwy|hwy|int|la|lp|mi|mr|pde|pwy|ps|pt|pro|qs|ra|rge|rd|rty|rw|sp|st|tce|tk|trl|tn|vs|wk|wy|cl|ct|cy|ce|cro|dl|el|gp|gns|gl|gm|gr|hts|lkt|me|pl|pa|rt|ri|sh|sq|tp|tr|vl|vw|dv|bvd)\b

正如所说,这不是一个简单的过程。使用上述算法,我们能够得到相当不错的结果。以这种方式解析两个地址后,您可以比较组件以确定它们是否相同。

还值得注意的是,不同国家/地区如何使用不同的地址格式。由于我们正在查看澳大利亚地址,因此您可能需要稍作修改。我想,原则是一样的。

希望这会有所帮助。

【讨论】:

  • 很好的答案!非常感谢!
猜你喜欢
  • 2017-03-15
  • 1970-01-01
  • 1970-01-01
  • 2015-11-22
  • 1970-01-01
  • 2015-01-20
  • 2021-07-22
  • 2016-12-15
  • 1970-01-01
相关资源
最近更新 更多