แยกวิเคราะห์ที่อยู่ที่ใช้งานได้เมืองรัฐรหัสไปรษณีย์จากสตริง [ปิด]


131

ปัญหา: ฉันมีช่องที่อยู่จากฐานข้อมูล Access ซึ่งถูกแปลงเป็น Sql Server 2005 ช่องนี้มีทุกอย่างในช่องเดียว ฉันต้องการแยกวิเคราะห์แต่ละส่วนของที่อยู่ลงในช่องที่เหมาะสมในตารางปกติ ฉันต้องทำสิ่งนี้ประมาณ 4,000 บันทึกและต้องทำซ้ำได้

สมมติฐาน:

  1. สมมติว่ามีที่อยู่ในสหรัฐอเมริกา (สำหรับตอนนี้)

  2. สมมติว่าบางครั้งสตริงอินพุตจะมีผู้รับ (บุคคลที่ถูกส่งถึง) และ / หรือที่อยู่ที่สอง (เช่น Suite B)

  3. รัฐอาจจะย่อ

  4. รหัสไปรษณีย์อาจเป็นตัวเลขมาตรฐาน 5 หลักหรือ zip + 4

  5. มีการพิมพ์ผิดในบางกรณี

อัปเดต: ในการตอบคำถามที่วางไว้มาตรฐานไม่ได้เป็นไปตามสากลฉันจำเป็นต้องจัดเก็บค่าแต่ละค่าไม่ใช่เฉพาะรหัสพิกัดทางภูมิศาสตร์และข้อผิดพลาดหมายถึงการพิมพ์ผิด (แก้ไขด้านบน)

ข้อมูลตัวอย่าง:

  • AP Croll & Son 2299 Lewes-Georgetown Hwy, Georgetown, DE 19947

  • 11522 Shawnee Road, กรีนวูด DE 19950

  • 144 Kings Highway, SW Dover, DE 19901

  • รวม Const. บริการ 2 Penns Way Suite 405 New Castle, DE 19720

  • Humes Realty 33 Bridle Ridge Court, Lewes, DE 19958

  • Nichols Excavation 2742 Pulaski Hwy Newark, DE 19711

  • 2284 Bryn Zion Road, Smyrna, DE 19904

  • VEI Dover Crossroads, LLC 1500 Serpentine Road, Suite 100 Baltimore MD 21

  • 580 North Dupont Highway Dover, DE 19901

  • ตู้ป ณ . 778 Dover, DE 19903


คำถามสองสามข้อ: 1. ตัวคั่นใด ๆ ? 2. ลำดับฟิลด์ในสตริงคืออะไร? 3. พฤติกรรมใดที่คุณต้องการในกรณีข้อมูลผิดพลาด (เช่นผลักที่อยู่ลงในช่องเดียวในตาราง SQL เว้นว่างไว้)
Jay Mooney

คำถามที่ดีและคำตอบที่น่าสนใจมาก การทำงานย้อนกลับจาก zip ดูเหมือนจะเป็นเรื่องธรรมดา แต่ถ้าคุณรับข้อมูลดิบจากลูกค้าซิปอาจไม่ถูกต้อง ฉันเดาว่าไซต์ส่วนใหญ่มีจำนวนที่อยู่ที่ไม่ได้สัดส่วนเช่น 90210
Kevin Williams

4
@ เควิน: ใช่เพราะคุณเป็นคนอเมริกันชอบที่จะล็อกพวกเราชาวแคนาดาโดยต้องใช้รหัส "ไปรษณีย์" และไม่ยอมรับรหัสไปรษณีย์ของเราจึงบังคับให้เราต้องป้อนสิ่งที่ไม่เป็นระเบียบเพื่อข้ามระบบ .... น่าเสียดายที่ซิปเดียวที่ฉัน รู้ว่า 90210 :-) แก้ไข: ไม่เป็นไร ... ดูเหมือนว่าคุณจะอยู่ห่างจากฉันไม่กี่กิโลเมตรในค. ศ. คุณก็คงทำเหมือนกัน :-P
mpen

2
ดูคำถาม SO นี้เพื่อดูภาพรวมเพิ่มเติมของสิ่งนี้
Matt

คำตอบ:


118

ฉันได้ทำงานมากมายเกี่ยวกับการแยกวิเคราะห์ประเภทนี้ เนื่องจากมีข้อผิดพลาดคุณจะไม่ได้รับความแม่นยำ 100% แต่มีบางสิ่งที่คุณสามารถทำได้เพื่อให้ได้ประโยชน์สูงสุดจากนั้นทำการทดสอบ BS ด้วยภาพ นี่คือวิธีทั่วไปในการดำเนินการ ไม่ใช่รหัสเพราะมันค่อนข้างเป็นวิชาการที่จะเขียนมันไม่มีความแปลกอะไรมีแค่การจัดการสตริงมากมาย

(ตอนนี้คุณได้โพสต์ข้อมูลตัวอย่างแล้วฉันได้ทำการเปลี่ยนแปลงเล็กน้อย)

  1. ทำงานย้อนหลัง เริ่มจากรหัสไปรษณีย์ซึ่งจะอยู่ใกล้กับจุดสิ้นสุดและหนึ่งในสองรูปแบบที่รู้จัก: XXXXX หรือ XXXXX-XXXX หากไม่ปรากฏขึ้นคุณสามารถสมมติว่าคุณอยู่ในเมืองส่วนของรัฐด้านล่าง
  2. สิ่งต่อไปก่อน zip จะเป็นสถานะและจะอยู่ในรูปแบบอักษรสองตัวหรือเป็นคำ คุณก็รู้ว่าสิ่งเหล่านี้จะเป็นอย่างไรมีเพียง 50 คนเท่านั้น นอกจากนี้คุณสามารถเปล่งเสียงคำเพื่อช่วยชดเชยข้อผิดพลาดในการสะกดคำได้
  3. ก่อนหน้านั้นคือเมืองและน่าจะอยู่ในแนวเดียวกันกับรัฐ คุณสามารถใช้ฐานข้อมูลรหัสไปรษณีย์เพื่อตรวจสอบเมืองและรัฐตามรหัสไปรษณีย์หรืออย่างน้อยก็ใช้เป็นเครื่องตรวจจับ BS
  4. โดยทั่วไปที่อยู่จะเป็นหนึ่งหรือสองบรรทัด บรรทัดที่สองโดยทั่วไปจะเป็นหมายเลขห้องชุดหากมี แต่อาจเป็นตู้ป ณ .
  5. แทบจะเป็นไปไม่ได้เลยที่จะตรวจพบชื่อในบรรทัดแรกหรือบรรทัดที่สองแม้ว่าจะไม่ได้ขึ้นต้นด้วยตัวเลข (หรือถ้าขึ้นต้นด้วย "attn:" หรือ "ให้ความสนใจกับ:" ก็อาจให้คำใบ้เป็น ไม่ว่าจะเป็นชื่อหรือบรรทัดที่อยู่

ฉันหวังว่านี่จะช่วยได้บ้าง


14
แม้ว่าจะเป็นเรื่องจริงที่มี 50 รัฐ USPS กล่าวว่ามีตัวย่อสองตัวอักษร 59 ตัวในโดเมนของ United States Postal Service 65 หากคุณนับกองกำลังติดอาวุธของอเมริกา usps.com/send/official-ab ย่อ. htm
Mike Sherrill 'Cat Recall'

17
"เพียง 50" เป็นการระบุว่ามีจำนวนน้อยมาก มันอาจจะ "แค่ 65" แต่นั่นไม่ใช่สิ่งสำคัญในการแก้ปัญหาในมือ
Tim Sullivan

4
อัลกอริทึมนี้ยังมีรายละเอียดอยู่ในUSPS Publication 28
Matt

92

ฉันคิดว่าการเอาท์ซอร์สปัญหาเป็นทางออกที่ดีที่สุด: ส่งไปยัง geocoder ของ Google (หรือ Yahoo) geocoder ไม่เพียงส่งคืน lat / long (ซึ่งไม่เป็นที่สนใจที่นี่) แต่ยังรวมถึงการแยกวิเคราะห์ที่อยู่ที่สมบูรณ์พร้อมด้วยช่องที่กรอกข้อมูลที่คุณไม่ได้ส่ง (รวมถึง ZIP + 4 และเคาน์ตี)

ตัวอย่างเช่นการแยกวิเคราะห์ "1600 Amphitheatre Parkway, Mountain View, CA" จะให้ผลตอบแทน

{
  "name": "1600 Amphitheatre Parkway, Mountain View, CA, USA",
  "Status": {
    "code": 200,
    "request": "geocode"
  },
  "Placemark": [
    {
      "address": "1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA",
      "AddressDetails": {
        "Country": {
          "CountryNameCode": "US",
          "AdministrativeArea": {
            "AdministrativeAreaName": "CA",
            "SubAdministrativeArea": {
              "SubAdministrativeAreaName": "Santa Clara",
              "Locality": {
                "LocalityName": "Mountain View",
                "Thoroughfare": {
                  "ThoroughfareName": "1600 Amphitheatre Pkwy"
                },
                "PostalCode": {
                  "PostalCodeNumber": "94043"
                }
              }
            }
          }
        },
        "Accuracy": 8
      },
      "Point": {
        "coordinates": [-122.083739, 37.423021, 0]
      }
    }
  ]
}

ตอนนี้ที่ parseable!


4
เนื่องจากนี่เป็นกระบวนการแบตช์ฉันจึงขอแนะนำให้ใช้เธรดพูลในการทำ geocoding เพื่อให้คุณสามารถส่งที่อยู่หลายรายการพร้อมกัน (Google รองรับอินเทอร์เฟซแบบแบตช์ทุกประเภทหรือไม่)
David

สิ่งนี้จะช่วยไม่ได้จริงๆกับที่อยู่บรรทัดที่สอง (ไพน์ 5 ในคำถาม)
Christopher Mahan

71
ข้อกำหนดในการให้บริการมักเป็นปัจจัย จำกัด สำหรับการใช้งานเชิงพาณิชย์และ / หรือที่ไม่เปิดเผยต่อสาธารณะ
Jay

นี่เป็นวิธีแก้ปัญหาที่ดี แต่มีบางกรณีที่ Google / Yahoo ไม่ส่งคืนผลลัพธ์เช่นที่อยู่ใหม่และที่อยู่ที่ขาดหายไปในฐานข้อมูล
Peter DeWeese

นี่จะเป็นทางออกที่ดี "IF" google ไม่ได้ จำกัด การเรียกแบบกลุ่มไปยัง API ของ MAPS
Hector

25

ผู้โพสต์ต้นฉบับมีแนวโน้มที่จะดำเนินต่อไปนานแล้ว แต่ฉันแทงไปที่การย้าย Perl Geo :: StreetAddress:โมดูลของสหรัฐอเมริกาที่ใช้โดยgeocoder.usไปยัง C # ทิ้งลงใน CodePlex และคิดว่าผู้คนที่สะดุดกับคำถามนี้ในอนาคตอาจ พบว่ามีประโยชน์:

ตัวแยกวิเคราะห์ที่อยู่ในสหรัฐอเมริกา

ในโฮมเพจของโครงการฉันพยายามพูดถึงข้อ จำกัด (จริงมาก) เนื่องจากฐานข้อมูล USPS ของที่อยู่ที่ถูกต้องไม่ได้รับการสนับสนุนการแยกวิเคราะห์จึงอาจคลุมเครือและไม่สามารถยืนยันหรือปฏิเสธความถูกต้องของที่อยู่ที่ระบุได้ มันสามารถพยายามดึงข้อมูลออกจากสตริง

มีไว้สำหรับในกรณีที่คุณต้องการรับชุดข้อมูลส่วนใหญ่ในฟิลด์ที่ถูกต้องหรือต้องการให้ทางลัดในการป้อนข้อมูล (ให้ผู้ใช้วางที่อยู่ลงในกล่องข้อความแทนการแท็บในหลายฟิลด์) มันเป็นเรื่องที่ไม่ได้มีความหมายสำหรับการตรวจสอบการส่งของที่อยู่

มันไม่ได้พยายามที่จะแยกวิเคราะห์สิ่งที่อยู่เหนือเส้นถนน แต่อาจมีคนใช้ regex เพื่อให้ได้สิ่งที่ใกล้เคียงพอสมควร - ฉันอาจจะทำลายมันที่บ้านเลขที่


17

SmartyStreets มีคุณลักษณะใหม่ที่แยกแอดเดรสออกจากสตริงอินพุตโดยพลการ (หมายเหตุ: ฉันไม่ได้ทำงานที่ SmartyStreets)

มันแยกที่อยู่ทั้งหมดออกจากข้อมูลตัวอย่างที่ระบุไว้ในคำถามด้านบน (อย่างไรก็ตามมีเพียง 9 จาก 10 ที่อยู่เท่านั้นที่ถูกต้อง)

นี่คือผลลัพธ์บางส่วน:ป้อนคำอธิบายภาพที่นี่

และนี่คือผลลัพธ์ในรูปแบบ CSV ของคำขอเดียวกันนั้น:

ID,Start,End,Segment,Verified,Candidate,Firm,FirstLine,SecondLine,LastLine,City,State,ZIPCode,County,DpvFootnotes,DeliveryPointBarcode,Active,Vacant,CMRA,MatchCode,Latitude,Longitude,Precision,RDI,RecordType,BuildingDefaultIndicator,CongressionalDistrict,Footnotes
1,32,79,"2299 Lewes-Georgetown Hwy, Georgetown, DE 19947",N,,,,,,,,,,,,,,,,,,,,,,
2,81,119,"11522 Shawnee Road, Greenwood DE 19950",Y,0,,11522 Shawnee Rd,,Greenwood DE 19950-5209,Greenwood,DE,19950,Sussex,AABB,199505209226,Y,N,N,Y,38.82865,-75.54907,Zip9,Residential,S,,AL,N#
3,121,160,"144 Kings Highway, S.W. Dover, DE 19901",Y,0,,144 Kings Hwy,,Dover DE 19901-7308,Dover,DE,19901,Kent,AABB,199017308444,Y,N,N,Y,39.16081,-75.52377,Zip9,Commercial,S,,AL,L#
4,190,232,"2 Penns Way Suite 405 New Castle, DE 19720",Y,0,,2 Penns Way Ste 405,,New Castle DE 19720-2407,New Castle,DE,19720,New Castle,AABB,197202407053,Y,N,N,Y,39.68332,-75.61043,Zip9,Commercial,H,,AL,N#
5,247,285,"33 Bridle Ridge Court, Lewes, DE 19958",Y,0,,33 Bridle Ridge Cir,,Lewes DE 19958-8961,Lewes,DE,19958,Sussex,AABB,199588961338,Y,N,N,Y,38.72749,-75.17055,Zip7,Residential,S,,AL,L#
6,306,339,"2742 Pulaski Hwy Newark, DE 19711",Y,0,,2742 Pulaski Hwy,,Newark DE 19702-3911,Newark,DE,19702,New Castle,AABB,197023911421,Y,N,N,Y,39.60328,-75.75869,Zip9,Commercial,S,,AL,A#
7,341,378,"2284 Bryn Zion Road, Smyrna, DE 19904",Y,0,,2284 Bryn Zion Rd,,Smyrna DE 19977-3895,Smyrna,DE,19977,Kent,AABB,199773895840,Y,N,N,Y,39.23937,-75.64065,Zip7,Residential,S,,AL,A#N#
8,406,450,"1500 Serpentine Road, Suite 100 Baltimore MD",Y,0,,1500 Serpentine Rd Ste 100,,Baltimore MD 21209-2034,Baltimore,MD,21209,Baltimore,AABB,212092034250,Y,N,N,Y,39.38194,-76.65856,Zip9,Commercial,H,,03,N#
9,455,495,"580 North Dupont Highway Dover, DE 19901",Y,0,,580 N DuPont Hwy,,Dover DE 19901-3961,Dover,DE,19901,Kent,AABB,199013961803,Y,N,N,Y,39.17576,-75.5241,Zip9,Commercial,S,,AL,N#
10,497,525,"P.O. Box 778 Dover, DE 19903",Y,0,,PO Box 778,,Dover DE 19903-0778,Dover,DE,19903,Kent,AABB,199030778781,Y,N,N,Y,39.20946,-75.57012,Zip5,Residential,P,,AL,

ฉันเป็นผู้พัฒนาที่เขียนบริการในตอนแรก อัลกอริทึมที่เรานำมาใช้นั้นแตกต่างจากคำตอบใด ๆ ที่นี่เล็กน้อย แต่ที่อยู่ที่แยกแต่ละรายการจะได้รับการยืนยันกับ API การค้นหาที่อยู่ดังนั้นคุณจึงมั่นใจได้ว่าถูกต้องหรือไม่ รับประกันผลการตรวจสอบแต่ละรายการ แต่เราทราบดีว่าผลลัพธ์อื่น ๆ จะไม่สมบูรณ์แบบเนื่องจากตามที่ได้ระบุไว้อย่างชัดเจนในชุดข้อความนี้ที่อยู่ไม่สามารถคาดเดาได้แม้ในบางครั้งสำหรับมนุษย์


2
Smartystreets ทำได้ดีอย่างเหลือเชื่อในสิ่งที่พวกเขาทำ มีความสุขมากที่ทราบว่านี่คือ API ที่พวกเขารองรับ
ftrotter

16

ฉันเคยทำสิ่งนี้มาแล้วในอดีต

ไม่ว่าจะทำด้วยตนเอง (สร้าง gui ที่ดีที่ช่วยให้ผู้ใช้ดำเนินการได้อย่างรวดเร็ว) หรือทำให้เป็นอัตโนมัติและตรวจสอบกับฐานข้อมูลที่อยู่ล่าสุด (คุณต้องซื้อ) และจัดการข้อผิดพลาดด้วยตนเอง

การจัดการด้วยตนเองจะใช้เวลาประมาณ 10 วินาทีในแต่ละครั้งซึ่งหมายความว่าคุณทำได้ 3600/10 = 360 ต่อชั่วโมงดังนั้น 4000 ควรใช้เวลาประมาณ 11-12 ชั่วโมง สิ่งนี้จะให้อัตราความแม่นยำสูง

สำหรับระบบอัตโนมัติคุณต้องมีฐานข้อมูลที่อยู่ล่าสุดในสหรัฐอเมริกาและปรับเปลี่ยนกฎของคุณกับสิ่งนั้น ฉันไม่แนะนำให้ใช้ regex (ยากที่จะรักษาในระยะยาวมีข้อยกเว้นมากมาย) ทำการจับคู่ 90% กับฐานข้อมูลทำส่วนที่เหลือด้วยตนเอง

รับสำเนามาตรฐานที่อยู่ไปรษณีย์ (USPS) ได้ที่http://pe.usps.gov/cpim/ftp/pubs/Pub28/pub28.pdfและสังเกตว่ามีความยาวมากกว่า 130 หน้า Regexes ที่จะนำไปใช้นั้นจะเป็นถั่ว

สำหรับที่อยู่ต่างประเทศการเดิมพันทั้งหมดจะถูกปิด คนงานในสหรัฐฯจะไม่สามารถตรวจสอบความถูกต้องได้

หรือใช้บริการข้อมูล อย่างไรก็ตามฉันไม่มีคำแนะนำ

นอกจากนี้: เมื่อคุณส่งสิ่งของทางไปรษณีย์ (มีไว้เพื่ออะไรใช่ไหม) ตรวจสอบให้แน่ใจว่าคุณใส่ "ขอแก้ไขที่อยู่" บนซองจดหมาย (ในตำแหน่งที่ถูกต้อง) และอัปเดตฐานข้อมูล (เราทำกุยง่ายๆให้พนักงานต้อนรับทำแบบนั้นคนที่จัดเรียงทางไปรษณีย์)

สุดท้ายเมื่อคุณขัดข้อมูลแล้วให้มองหารายการที่ซ้ำกัน


14

หลังจากคำแนะนำที่นี่ฉันได้คิดค้นฟังก์ชันต่อไปนี้ใน VB ซึ่งสร้างผ่านได้แม้ว่าจะไม่สมบูรณ์แบบเสมอไป (หากมีการระบุชื่อ บริษัท และสายผลิตภัณฑ์ แต่ก็รวมข้อมูลที่ใช้งานได้กับชุดและเมืองเข้าด้วยกัน โปรดอย่าลังเลที่จะแสดงความคิดเห็น / refactor / ตะโกนใส่ฉันที่ทำผิดกฎของตัวเอง ฯลฯ :

Public Function parseAddress(ByVal input As String) As Collection
    input = input.Replace(",", "")
    input = input.Replace("  ", " ")
    Dim splitString() As String = Split(input)
    Dim streetMarker() As String = New String() {"street", "st", "st.", "avenue", "ave", "ave.", "blvd", "blvd.", "highway", "hwy", "hwy.", "box", "road", "rd", "rd.", "lane", "ln", "ln.", "circle", "circ", "circ.", "court", "ct", "ct."}
    Dim address1 As String
    Dim address2 As String = ""
    Dim city As String
    Dim state As String
    Dim zip As String
    Dim streetMarkerIndex As Integer

    zip = splitString(splitString.Length - 1).ToString()
    state = splitString(splitString.Length - 2).ToString()
    streetMarkerIndex = getLastIndexOf(splitString, streetMarker) + 1
    Dim sb As New StringBuilder

    For counter As Integer = streetMarkerIndex To splitString.Length - 3
        sb.Append(splitString(counter) + " ")
    Next counter
    city = RTrim(sb.ToString())
    Dim addressIndex As Integer = 0

    For counter As Integer = 0 To streetMarkerIndex
        If IsNumeric(splitString(counter)) _
            Or splitString(counter).ToString.ToLower = "po" _
            Or splitString(counter).ToString().ToLower().Replace(".", "") = "po" Then
                addressIndex = counter
            Exit For
        End If
    Next counter

    sb = New StringBuilder
    For counter As Integer = addressIndex To streetMarkerIndex - 1
        sb.Append(splitString(counter) + " ")
    Next counter

    address1 = RTrim(sb.ToString())

    sb = New StringBuilder

    If addressIndex = 0 Then
        If splitString(splitString.Length - 2).ToString() <> splitString(streetMarkerIndex + 1) Then
            For counter As Integer = streetMarkerIndex To splitString.Length - 2
                sb.Append(splitString(counter) + " ")
            Next counter
        End If
    Else
        For counter As Integer = 0 To addressIndex - 1
            sb.Append(splitString(counter) + " ")
        Next counter
    End If
    address2 = RTrim(sb.ToString())

    Dim output As New Collection
    output.Add(address1, "Address1")
    output.Add(address2, "Address2")
    output.Add(city, "City")
    output.Add(state, "State")
    output.Add(zip, "Zip")
    Return output
End Function

Private Function getLastIndexOf(ByVal sArray As String(), ByVal checkArray As String()) As Integer
    Dim sourceIndex As Integer = 0
    Dim outputIndex As Integer = 0
    For Each item As String In checkArray
        For Each source As String In sArray
            If source.ToLower = item.ToLower Then
                outputIndex = sourceIndex
                If item.ToLower = "box" Then
                    outputIndex = outputIndex + 1
                End If
            End If
            sourceIndex = sourceIndex + 1
        Next
        sourceIndex = 0
    Next
    Return outputIndex
End Function

การส่งผ่านparseAddressฟังก์ชัน "AP Croll & Son 2299 Lewes-Georgetown Hwy, Georgetown, DE 19947" ส่งกลับ:

2299 Lewes-Georgetown Hwy
A. P. Croll & Son  
Georgetown
DE
19947

13

ฉันทำงานในโดเมนการประมวลผลที่อยู่มาประมาณ 5 ปีแล้วและไม่มีกระสุนเงินเลย วิธีแก้ปัญหาที่ถูกต้องจะขึ้นอยู่กับค่าของข้อมูล หากไม่มีค่ามากให้ส่งผ่านโปรแกรมแยกวิเคราะห์ตามที่คำตอบอื่นแนะนำ หากมันค่อนข้างมีค่าคุณจะต้องให้มนุษย์ประเมิน / แก้ไขผลลัพธ์ทั้งหมดของโปรแกรมแยกวิเคราะห์ หากคุณกำลังมองหาโซลูชันอัตโนมัติที่ทำซ้ำได้ทั้งหมดคุณอาจต้องการพูดคุยกับผู้ให้บริการแก้ไขที่อยู่เช่น Group1 หรือ Trillium


8

วิธีนี้จะไม่ช่วยแก้ปัญหาของคุณ แต่ถ้าคุณต้องการเพียงข้อมูล lat / long สำหรับที่อยู่เหล่านี้ Google Maps API จะแยกวิเคราะห์ที่อยู่ที่ไม่ได้จัดรูปแบบได้ดี

ข้อเสนอแนะที่ดีหรือคุณสามารถดำเนินการขอ CURL สำหรับที่อยู่แต่ละรายการไปยัง Google Maps และจะส่งคืนที่อยู่ที่มีรูปแบบถูกต้อง จากนั้นคุณสามารถ regex เป็นเนื้อหาในใจ


7

+1 ในโซลูชันที่แนะนำของ James A. Rosen เนื่องจากได้ผลดีสำหรับฉันอย่างไรก็ตามสำหรับเว็บไซต์ที่สมบูรณ์นี้เป็นการอ่านที่น่าสนใจและเป็นความพยายามที่ดีที่สุดที่ฉันเคยเห็นในการจัดทำเอกสารที่อยู่ทั่วโลก: http://www.columbia.edu/kermit /postal.html


6

มีมาตรฐานใด ๆ ในการบันทึกที่อยู่หรือไม่? ตัวอย่างเช่น:

  1. มีเครื่องหมายจุลภาคหรือบรรทัดใหม่ที่แยก street1 จาก street2 จากเมืองจากรัฐจาก zip หรือไม่?
  2. ประเภทที่อยู่ (ถนนถนนบูเลอวาร์ด ฯลฯ ) มีการสะกดคำเสมอหรือไม่ ย่อเสมอ? บางส่วนของแต่ละ?
  3. กำหนด "ข้อผิดพลาด"

คำตอบทั่วไปของฉันคือชุดของนิพจน์ทั่วไปแม้ว่าความซับซ้อนของสิ่งนี้จะขึ้นอยู่กับคำตอบ และหากไม่มีความสอดคล้องกันเลยคุณอาจประสบความสำเร็จเพียงบางส่วนด้วย Regex (เช่น: การกรองรหัสไปรษณีย์และสถานะ) และจะต้องดำเนินการส่วนที่เหลือด้วยมือ (หรืออย่างน้อยก็ผ่านส่วนที่เหลือให้มาก อย่างรอบคอบเพื่อให้แน่ใจว่าคุณพบข้อผิดพลาด)


6

ขอข้อมูลตัวอย่างอีก

ดังที่ได้กล่าวไปแล้วฉันจะทำงานย้อนกลับจากซิป

เมื่อคุณมี zip ฉันจะค้นหาฐานข้อมูล zip เก็บผลลัพธ์และลบออกและ zip ออกจากสตริง

ที่จะทำให้คุณยุ่งกับที่อยู่ ที่อยู่ MOST (ทั้งหมด?) จะเริ่มต้นด้วยตัวเลขดังนั้นให้ค้นหาตัวเลขที่เกิดขึ้นครั้งแรกในสตริงที่เหลือและจับทุกอย่างจากนั้นไปยังจุดสิ้นสุด (ใหม่) ของสตริง นั่นจะเป็นที่อยู่ของคุณ ทุกสิ่งที่อยู่ทางซ้ายของหมายเลขนั้นน่าจะเป็นผู้รับ

ตอนนี้คุณควรมีเมืองรัฐและ Zip เก็บไว้ในตารางและอาจเป็นสองสตริงผู้รับและที่อยู่ สำหรับที่อยู่โปรดตรวจสอบว่ามี "ห้องชุด" หรือ "ห้องชุด" หรือไม่ ฯลฯ และแบ่งออกเป็นสองค่า (ที่อยู่บรรทัดที่ 1 และ 2)

สำหรับผู้รับฉันจะถ่อและจับคำสุดท้ายของสตริงนั้นเป็นนามสกุลและใส่ส่วนที่เหลือลงในฟิลด์ชื่อ หากคุณไม่ต้องการทำเช่นนั้นคุณจะต้องตรวจสอบคำทักทาย (นายนางสาวดร. ฯลฯ ) เมื่อเริ่มต้นและตั้งสมมติฐานตามจำนวนช่องว่างว่าชื่อเป็นอย่างไร สร้างขึ้น

ฉันไม่คิดว่าจะมีวิธีใดที่คุณสามารถแยกวิเคราะห์ได้อย่างแม่นยำ 100%


6

ลองwww.address-parser.com เราใช้บริการเว็บของพวกเขาซึ่งคุณสามารถทดสอบออนไลน์ได้


1
วิธีนี้ใช้ได้ดีกับบางสิ่งเช่นการค้นหาที่อยู่ในเอกสาร html ขนาดใหญ่ ฉันแค่หวังว่าพวกเขาจะมีอินเทอร์เฟซ REST ไม่ใช่ SOAP ขอบคุณสำหรับการแบ่งปันลิงค์นี้
jspooner

1
หากคุณมีส่วนเกี่ยวข้องกับพวกเขาคุณจะต้องเปิดเผยสิ่งนั้น
Matt

1
คงจะดีไม่น้อยหากพวกเขาประเมินราคาแทนที่จะเรียกร้องให้ฉันบอกพวกเขาว่าบริการของพวกเขามีคุณค่าเพียงใดก่อนที่จะให้ราคา
เครื่องปิ้งขนมปัง

5

จากข้อมูลตัวอย่าง:

  1. ฉันจะเริ่มต้นที่ส่วนท้ายของสตริง แยกวิเคราะห์รหัสไปรษณีย์ (รูปแบบใดรูปแบบหนึ่ง) อ่านจบที่ช่องว่างแรก หากไม่พบรหัสไปรษณีย์ Error

  2. ตัดส่วนท้ายสำหรับช่องว่างและอักขระพิเศษ (ลูกน้ำ)

  3. จากนั้นไปที่สถานะอีกครั้งใช้ช่องว่างเป็นตัวคั่น อาจใช้รายการค้นหาเพื่อตรวจสอบรหัสสถานะตัวอักษร 2 ตัวและชื่อรัฐแบบเต็ม หากไม่พบสถานะที่ถูกต้องข้อผิดพลาด

  4. ตัดช่องว่างและลูกน้ำจากท้ายอีกครั้ง

  5. เมืองเป็นเรื่องยุ่งยากฉันจะใช้จุลภาคที่นี่โดยเสี่ยงที่จะได้รับข้อมูลมากเกินไปในเมือง มองหาลูกน้ำหรือจุดเริ่มต้นของบรรทัด

  6. หากคุณยังมีตัวอักษรเหลืออยู่ในสตริงให้ใส่อักขระทั้งหมดลงในช่องที่อยู่

สิ่งนี้ไม่สมบูรณ์แบบ แต่ควรเป็นจุดเริ่มต้นที่ดีทีเดียว


4

หากเป็นข้อมูลที่มนุษย์ป้อนคุณจะใช้เวลามากเกินไปในการพยายามเขียนโค้ดเกี่ยวกับข้อยกเว้น

ลอง:

  1. นิพจน์ทั่วไปเพื่อแยกรหัสไปรษณีย์

  2. ค้นหารหัสไปรษณีย์ (ผ่านฐานข้อมูลของรัฐบาลที่เหมาะสม) เพื่อรับที่อยู่ที่ถูกต้อง

  3. รับนักศึกษาฝึกงานเพื่อตรวจสอบข้อมูลใหม่ที่ตรงกับข้อมูลเก่าด้วยตนเอง


3

วิธีนี้จะไม่ช่วยแก้ปัญหาของคุณ แต่ถ้าคุณต้องการเพียงข้อมูล lat / long สำหรับที่อยู่เหล่านี้ Google Maps API จะแยกวิเคราะห์ที่อยู่ที่ไม่ได้จัดรูปแบบได้ดี


3

RecogniContact เป็นวัตถุ Windows COM ที่แยกวิเคราะห์ที่อยู่ของสหรัฐอเมริกาและยุโรป คุณสามารถลองใช้งานได้ที่ http://www.loquisoft.com/index.php?page=8


ดูเหมือนว่า RecogniContact จะปิดให้บริการแก่สาธารณะ การเข้าถึงต้องส่งแบบฟอร์มติดต่อ แต่ไม่มีการตอบกลับ อาจมีคนอื่นรู้วิธีติดต่อกับพวกเขา
ลุคแวนใน


3

ปัญหาประเภทนี้แก้ไขได้ยากเนื่องจากมีความคลุมเครือในข้อมูล

นี่คือโซลูชันที่ใช้ Perl ซึ่งกำหนดโครงสร้างไวยากรณ์แบบสืบเชื้อสายซ้ำตามนิพจน์ทั่วไปเพื่อแยกวิเคราะห์การรวมกันของที่อยู่ที่ถูกต้องจำนวนมาก: http://search.cpan.org/~kimryan/Lingua-EN-AddressParse-1.20/lib/Lingua /EN/AddressParse.pm . ซึ่งรวมถึงคุณสมบัติย่อยภายในที่อยู่เช่น 12 1st Avenue N Suite # 2 Somewhere CA 12345 USA

มันคล้ายกับhttp://search.cpan.org/~timb/Geo-StreetAddress-US-1.03/US.pmกล่าวถึงข้างต้น แต่ยังใช้ได้กับที่อยู่ที่ไม่ได้มาจากสหรัฐอเมริกาเช่นสหราชอาณาจักรออสเตรเลียและ แคนาดา.

นี่คือผลลัพธ์สำหรับหนึ่งในที่อยู่ตัวอย่างของคุณ โปรดทราบว่าส่วนชื่อจะต้องถูกลบออกก่อนจาก "AP Croll & Son 2299 Lewes-Georgetown Hwy, Georgetown, DE 19947" เพื่อลดเป็น "2299 Lewes-Georgetown Hwy, Georgetown, DE 19947" ทำได้อย่างง่ายดายโดยการลบข้อมูลทั้งหมดจนถึงตัวเลขแรกที่พบในสตริง

Non matching part       ''
Error                   '0'
Error descriptions      ''
Case all                '2299 Lewes-Georgetown Hwy Georgetown DE 19947'
COMPONENTS              ''
country                 ''
po_box_type             ''
post_box                ''
post_code               '19947'
pre_cursor              ''
property_identifier     '2299'
property_name           ''
road_box                ''
street                  'Lewes-Georgetown'
street_direction        ''
street_type             'Hwy'
sub_property_identifier ''
subcountry              'DE'
suburb                  'Georgetown'

2

เนื่องจากมีโอกาสผิดพลาดในคำลองนึกถึงการใช้ SOUNDEX ร่วมกับอัลกอริทึม LCS เพื่อเปรียบเทียบสตริงสิ่งนี้จะช่วยได้มาก!


2

ใช้ Google API

$d=str_replace(" ", "+", $address_url);
$completeurl ="http://maps.googleapis.com/maps/api/geocode/xml?address=".$d."&sensor=true"; 
$phpobject = simplexml_load_file($completeurl);
print_r($phpobject);

1
นั่นอาจขัดต่อข้อกำหนดในการให้บริการ แต่ดูเหมือนว่าจะใช้งานได้ - แม้ว่าจะอ่านคำถามซ้ำ แต่ก็ไม่ตรงกับข้อกำหนด
Jamie Bull

2

สำหรับนักพัฒนาทับทิมหรือรางมีอัญมณีดีๆที่เรียกว่าstreet_address street_addressฉันใช้สิ่งนี้กับหนึ่งในโครงการของฉันและได้ผลตามที่ฉันต้องการ

ปัญหาเดียวที่ฉันพบคือเมื่อใดก็ตามที่ที่อยู่อยู่ในรูปแบบนี้P. O. Box 1410 Durham, NC 27702 มันจะส่งคืนศูนย์ดังนั้นฉันจึงต้องแทนที่ "PO Box" ด้วย '' และหลังจากนั้นก็สามารถแยกวิเคราะห์ได้


ลิงก์ไปยังโมดูลด้านบนเสียให้ใช้สิ่งนี้แทน: search.cpan.org/~kimryan/Lingua-EN-AddressParse
Kim Ryan

1

มีบริการข้อมูลที่ระบุรหัสไปรษณีย์จะให้รายชื่อถนนแก่คุณในรหัสไปรษณีย์นั้น

ใช้ regex เพื่อแยก Zip หรือ City State - ค้นหารายการที่ถูกต้องหรือหากเกิดข้อผิดพลาดทั้งสองอย่าง ดึงรายชื่อถนนจากแหล่งข้อมูลแก้ไขเมืองและรัฐแล้วตามด้วยที่อยู่ เมื่อคุณได้รับที่อยู่บรรทัดที่ 1 เมืองรัฐและรหัสไปรษณีย์ที่ถูกต้องแล้วคุณสามารถตั้งสมมติฐานในที่อยู่บรรทัดที่ 2..3


1

ฉันไม่รู้ว่าสิ่งนี้จะเป็นไปได้อย่างไร แต่ฉันไม่เห็นสิ่งนี้กล่าวถึงดังนั้นฉันจึงคิดว่าจะดำเนินการต่อและแนะนำสิ่งนี้:

หากคุณเคร่งครัดในสหรัฐอเมริกา ... รับฐานข้อมูลขนาดใหญ่ของรหัสไปรษณีย์รัฐเมืองและถนนทั้งหมด ค้นหาสิ่งเหล่านี้ในที่อยู่ของคุณ คุณสามารถตรวจสอบสิ่งที่คุณพบได้โดยการทดสอบว่าเมืองที่คุณพบนั้นมีอยู่ในรัฐที่คุณพบหรือไม่หรือโดยการตรวจสอบว่าถนนที่คุณพบนั้นมีอยู่ในเมืองที่คุณพบหรือไม่ ถ้าไม่เป็นเช่นนั้นโอกาสที่จอห์นไม่ได้อยู่ที่ถนนของจอห์น แต่เป็นชื่อของผู้รับ ... โดยทั่วไปรับข้อมูลส่วนใหญ่ที่คุณสามารถทำได้และตรวจสอบที่อยู่ของคุณกับมัน ตัวอย่างที่ชัดเจนคือการได้รับรายชื่อที่อยู่ทั้งหมดในสหรัฐอเมริกาของ A จากนั้นค้นหาว่ารายการใดตรงกับที่อยู่ของคุณมากที่สุด ...


1

มีพอร์ตจาวาสคริปต์ของ Perl แพคเกจภูมิศาสตร์ :: StreetAddress :: สหรัฐ: https://github.com/hassansin/parse-address เป็นแบบ regex และทำงานได้ค่อนข้างดี

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.