宣布 Geo::libpostal

libpostal 是一个用于标准化和解析国际街址的 C 语言库。它由 OpenStreetMap 数据构建,支持超过 60 种语言的标准化,并能解析来自 100 多个国家的地址。它运行速度极快,现在您可以使用我编写的新模块 Geo::libpostal 在 Perl 中使用它。

标准化地址

假设您支持一个应用程序,该应用程序有客户注册流程,客户需要提供他们的地址。防止重复注册的一种方法是为每个地址只允许一个客户。但是,当客户每次输入地址略有不同时,您该如何处理这种情况呢?

一个答案就是使用 libpostal 的标准化功能,将单个地址字符串扩展为有效变体。如果您已经有客户的地址与这些变体之一匹配,那么您知道您有重复注册。假设您有一个地址为“216 Park Avenue Apt 17D, New York, NY 10022”的客户。然后,另一位客户以非常相似的地址“216 Park Ave Apt 17D, New York, NY 10022”出现。以下是如何使用 Perl 测试这种情况的方法

use Geo::libpostal 'expand_address';

my @original_variants = expand_address("216 Park Avenue Apt 17D, New York, NY 10022");

# @original_variants contains:
#   216 park avenue apartment 17d new york new york 10022
#   216 park avenue apartment 17d new york ny 10022

my @new_variants = expand_address("216 Park Ave Apt 17D, New York, NY 10022");

for my $address (@new_variants) {
  if (grep { $address eq $_ } @original_variants) {
    print "Duplicate address found!\n";
  }
}

expand_address() 支持大量的 选项:包括以多种语言返回结果、仅扩展地址的某些部分以及扩展地址的格式。

解析地址

libpostal 还可以将地址字符串解析为其组成部分,如房屋名称、编号、城市和邮政编码。这对于从信息提取到简化网页表单等各种用途都非常有用。以下是使用 Perl 解析地址字符串的方法

use Geo::libpostal 'parse_address';

my %address = parse_address("216 Park Avenue Apt 17D, New York, NY 10022");

# %address contains:
#    road         => 'park avenue apt 17d',
#    city         => 'new york',
#    postcode     => '10022',
#    state        => 'ny',
#    house_number => '216'

慢启动

为了尽可能快,libpostal 使用设置函数在内存中创建查找表。这些可能需要几秒钟才能构建,所以 Geo::libpostal 在底层会为您懒加载设置函数。这意味着第一次调用 expand_addressparse_address 的速度会比平时慢得多,因为此时设置函数正在运行。

use Geo::libpostal 'expand_address';

# this is slow
@addresses = expand_address("216 Park Avenue Apt 17D, New York, NY 10022");

# this is fast!
@addresses = expand_address("76 Ninth Avenue, New York, NY 10111");

类似地,libpostal 还具有卸载查找表的销毁函数。Geo::libpostal 有一个内部函数 _teardown,它会在 END 块中自动调用,但您也可以直接调用它。唯一的效果是,随后的 expand_addressparse_address 调用将变慢,因为设置函数将再次被调用。使用 libpostal 的最新版本,在进程中多次调用设置或销毁是安全的。

参考文献


本文最初发布在 PerlTricks.com 上。

标签

David Farrell

David 是一名职业程序员,他经常 推文博客 关于代码和编程的艺术。

浏览他们的文章

反馈

这篇文章有什么问题吗?请通过在 GitHub 上打开一个问题或 pull request 来帮助我们。