Поиск адреса в строке - Python или Ruby

Эй, мне было интересно, как я могу найти уличный адрес в строке в Python/Ruby?

Может быть, с помощью регулярного выражения?

Кроме того, это будет в следующем формате (США)

420 Fanboy Lane, Купертино, Калифорния

Спасибо!

6 ответов

Решение

Используя ваш пример, это то, что я придумал в Ruby (я отредактировал его, чтобы включить ZIP-код и дополнительный +4 ZIP):

regex = Regexp.new(/^[0-9]* (.*), (.*) [a-zA-Z]{2} [0-9]{5}(-[0-9]{4})?$/)
addresses = ["420 Fanboy Lane, Cupertino CA 12345"]
addresses << "1829 William Tell Oveture, by Gioachino Rossini 88421"
addresses << "114801 Western East Avenue Apt. B32, Funky Township CA 12345"
addresses << "1 Infinite Loop, Cupertino CA 12345-1234"
addresses << "420 time!"

addresses.each do |address|
  print address
  if address.match(regex)
    puts " is an address"
  else
    puts " is not an address"
  end
end

# Outputs:
> 420 Fanboy Lane, Cupertino CA 12345 is an address  
> 1829 William Tell Oveture, by Gioachino Rossini 88421 is not an address  
> 114801 Western East Avenue Apt. B32, Funky Township CA 12345 is an address  
> 1 Infinite Loop, Cupertino CA 12345-1234 is an address  
> 420 time! is not an address  

Может быть, вы хотите взглянуть на pypostal. pypostal - это официальные привязки Python к libpostal.

С помощью примеров от Майка Бетани я сделал этот маленький пример:

from postal.parser import parse_address

addresses = [
    "420 Fanboy Lane, Cupertino CA 12345",
    "1829 William Tell Oveture, by Gioachino Rossini 88421",
    "114801 Western East Avenue Apt. B32, Funky Township CA 12345",
    "1 Infinite Loop, Cupertino CA 12345-1234",
    "420 time!",
]

for address in addresses:
    print parse_address(address)
    print "*" * 60

>     [(u'420', u'house_number'), (u'fanboy lane', u'road'), (u'cupertino', u'city'), (u'ca', u'state'), (u'12345', u'postcode')]
>     ************************************************************
>     [(u'1829', u'house_number'), (u'william tell', u'road'), (u'oveture by gioachino', u'house'), (u'rossini', u'road'), (u'88421',
> u'postcode')]
>     ************************************************************
>     [(u'114801', u'house_number'), (u'western east avenue apt.', u'road'), (u'b32', u'postcode'), (u'funky', u'road'), (u'township',
> u'city'), (u'ca', u'state'), (u'12345', u'postcode')]
>     ************************************************************
>     [(u'1', u'house_number'), (u'infinite loop', u'road'), (u'cupertino', u'city'), (u'ca', u'state'), (u'12345-1234',
> u'postcode')]
>     ************************************************************
>     [(u'420', u'house_number'), (u'time !', u'house')]
>     ************************************************************

Вот что я использовал:

(\d{1,10}( \w+){1,10}( ( \w+){1,10})?( \w+){1,10}[,.](( \w+){1,10}(,)? [A-Z]{2}( [0-9]{5})?)?) 

Он не идеален и не соответствует крайним случаям, но работает для большинства регулярно вводимых адресов и частичных адресов.

Он находит адреса в тексте, такие как

Привет! Я нахожусь в 12567 Некоторый Св. Фэйрфакс, Вирджиния. Прийти за мной!

какой-то текст 12567 какой-то св мой дом

что-то еще 123 My Street Drive, Fairfax VA 22033

Надеюсь, это поможет кому-то

\d{1,4}( \w+){1,3},( \w+){1,3} [A-Z]{2}

Не полностью проверено, но должно работать. Просто используйте его с вашей любимой функцией из re (например re.findall, Предположения:

  1. Номер дома может быть длиной от 1 до 4 цифр
  2. 1-3 номера следуют за номером дома, и все они разделены пробелами
  3. Название города - 1-3 слова (должно совпадать с Купертино, Лос-Анджелесом и Сан-Луис-Обиспо)

Хорошо, основываясь на очень полезных ответах Майка Бетани и Рэйфа Кеттлера (спасибо!), Я получаю этот REGEX для python и ruby. / [0-9] {1,4} (.), (.) [A-zA-Z] {2} [0-9] {5} /

Ruby Code - Результаты 12 Argonaut Lane, Lexington MA 02478

myregex=Regexp.new(/[0-9]{1,4} (.*), (.*) [a-zA-Z]{2} [0-9]{5}(-[0-9]{4})?/)

print "We're Having a pizza party at 12 Argonaut Lane, Lexington MA 02478 Come join the party!".match(myregex)

Python Code - не работает точно так же, но это базовый код.

import re
myregex = re.compile(r'/[0-9]{1,4} (.*), (.*) [a-zA-Z]{2} [0-9]{5}(-[0-9]{4})?/')
search = myregex.findall("We're Having a pizza party at 12 Argonaut Lane, Lexington MA 02478 Come join the party!")

Как уже говорилось, адреса очень свободной формы. Вместо подхода REGEX, как насчет сервиса, который предоставляет точные стандартизированные адресные данные? Я работаю на SmartyStreets, где мы предоставляем API, который делает именно это. Один простой запрос GET и ваш адрес проанализирован для вас. Попробуйте этот пример с питоном (вам нужно запустить пробную версию):

https://github.com/smartystreets/smartystreets-python-sdk/blob/master/examples/us_street_single_address_example.py

Другие вопросы по тегам