2010-12-28 9 views
2

Hey, Ich frage mich, wie ich eine Adresse in einer Zeichenfolge in Python/Ruby finden kann?Street Address Suche in einem String - Python oder Ruby

Vielleicht durch eine Regex?

Außerdem ist es sein würde im folgende Format (US)

420 Fanboy Lane, Cupertino CA

Dank!

+10

Obligatorisch: http://xkcd.com/208/ –

+0

Sie müßten einige vernünftigen Grenzen setzen, was ein „Adresse "ist. Wie viele Nummern kann es haben? Muss es ein richtiges Ende haben (z. B. Rd, St, Ct)? Wie viele Wörter kann es vor dem Ende haben (z. B. 1337 Old Stack Overflow Fragen Lane zu lang?) –

+0

Haha, lustig. Irgendwie was ich machen möchte. – Souleiman

Antwort

2

mit Ihrem Beispiel das ist, was ich kam mit in Ruby (ich es bearbeitet schließen Postleitzahl und eine optionale +4 PLZ):

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 
+0

Dieser Code funktioniert nicht für mich ... Datei "mini.py", Zeile 1 regex = Regexp.new (/^[0-9] * (. *), (. *) [a-zA-Z] {2} $ /) ^ SyntaxError: ungültige Syntax Aber danke! – Souleiman

+0

Das liegt daran, dass es Ruby ist, nicht Python. Entschuldigung, dachte das war offensichtlich. –

+0

Oh ja - ich bin ziemlich dumm. Es tut uns leid! (Ich war wie, was ist dieser Code, so komisch) Off, um Ruby zu installieren. DreamHost unterstützt es, oder?) Python und Rubin sind ähnlich, oder? – Souleiman

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

nicht vollständig getestet, aber funktionieren sollte. Verwenden Sie sie einfach mit Ihrer Lieblingsfunktion von re (zB re.findall Annahmen:.

  1. Eine Hausnummer
  2. zwischen 1 und 4 Ziffern lang sein kann
  3. 1-3 Worte folgen einer Hausnummer, und sie sind alle getrennt durch Leerzeichen
  4. Stadtname ist 1-3 Wörter (benötigt Cupertino, Los Angeles und San Luis Obispo entsprechen)
+0

+1 für eine gute Antwort, obwohl ich denke, dass meins besser ist;). Vor allem, weil es flexibler ist. Das heißt natürlich, dass ich auch mehr falsche Positive haben könnte. Ich ging auch mit Klein- und Großbuchstaben, weil ich annahm, dass Eingabe falsch eingegeben werden konnte. –

+0

@Mike '\ w' stimmt mit allem überein, was wie ein Wort aussieht, also werden Groß- und Kleinbuchstaben zusammenpassen. –

+0

Ja, aber du kannst nur bis zu 3 Wörter finden, meins passt zu allem. Das könnte das Problem auch bei mir sein, da es notwendigerweise mehr zusammenbringen wird. Oh, und ich meinte niedriger/höher für den Staat. Entschuldigung für die schlechte Kommunikation. –

0

Okay, Basierend auf den sehr hilfreich Mike Bethany und Rafe Kettler Antworten (Danke!) ich dieses REGEX für Python und Ruby arbeitet. /[0-9] {1,4}, (.) [A-zA-Z] {2} [0-9] {5}/

Ruby-Code (.) - Ergebnisse in 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 - funktioniert nicht ganz die gleiche, aber das ist der Basiscode.

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!") 
+0

Tack on '(- [0-9] {4})?' Am Ende und du bekommst auch optionale +4 ZIPs. –

+0

Ahah! So machen Sie etwas Wahlfreies - setzen Sie es in Klammern und setzen Sie ein? Danach? Vielen Dank! – Souleiman

0

Wie gesagt, Adressen sind sehr frei. Anstelle eines REGEX-Ansatzes, wie wäre es mit einem Service, der genaue, standardisierte Adressdaten liefert? Ich arbeite für SmartyStreets, wo wir eine API zur Verfügung stellen, die genau das tut. Eine einfache GET-Anfrage und Sie haben Ihre Adresse für Sie analysiert. Versuchen Sie, diese Python-Probe aus (Sie beginnen müssen eine trial):

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

+0

Das scheint wie ein cooler Service; Die Regexes funktionierten für mein damaliges Projekt gut. Ich überarbeite den Service und verwende etwas neu erworbenes Wissen, das Google Maps API tut dies und vieles mehr kostenlos.: P Die Deckel sind jedoch ein Nachteil. – Souleiman

+0

Gute Nachrichten, die Ergebnisse werden jetzt im Titel Fall (nicht alle CAPS) zurückgegeben. Ich werde diese Probe bald aktualisieren. – mdwhatcott

+0

BTW, beachten Sie, dass das Google Maps-API nicht garantieren kann, dass eine bestimmte Adresse derzeit echt und verfügbar ist - der USPS ist hier zuständig. – mdwhatcott

0

Hier ist, was ich verwendet:

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

Es ist nicht perfekt und nicht mit Grenzfälle, aber es funktioniert für die am häufigsten getippten Adressen und Teiladressen.

Es findet Adressen in Text wie

Hi! I'm at 12567 Some St. Fairfax, VA. Come get me!

some text 12567 Some St. is my home

something else 123 My Street Drive, Fairfax VA 22033

Hope this jemand, den Sie haben wollen

4

Vielleicht einen Blick auf pypostal hilft. pypostal sind die offiziellen Python-Bindungen zu libpostal.

Mit den Beispielen von Mike Bethany ich machte dieses kleine Beispiel:

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')] 
>  ************************************************************