RegEx'in PHP ile String Adres Özü

5 Cevap php

My Problem

Ben alan kişilerin tümü için Washington adreslerini bulmak için US House of Representatives Site üzerine bireysel bağlantıları taramasını çalışılıyor. Sorun, Washington adresin formatı zaman zaman değişir olmasıdır. Bazen zor maç yapmadan mermi, borular, yeni hatlar ve kırılmaya etiketleri vardır.


Ben büyük ölçüde benzer adreslerini almak için birçok sayfalarını taramaya çalışılıyor:

ignore peculiar whitespace. It's merely to show string-part similarities

    1433 Longworth House Office Building Washington,  D.C. 20515
     332 Cannon HOB                      Washington   DC   20515
    1641 LONGWORTH HOUSE OFFICE BUILDING WASHINGTON,  DC   20515
    1238 Cannon H.O.B. (line return)
    Washington, DC 20515
    8293 Longworth House Office Building • Washington DC • 20515
    8293 Longworth House Office Building | Washington DC | 20515

Bunların her biri ayrı ayrı, diğer metin ve html etiketleri ton çevrili geri gelecektir. Adresleri bile
içerebilir veya
adresin kendisi içinde.

Ne yapmak istiyorum kaynak dizeden ilk maçı yakalamak, ve bir değişkenin değeri olarak ayarlanır. Benim anlayış, bu iyi bir düzenli ifade ile yaklaştı olacaktır.

Update:

Bu gün görünebilir hangi çeşitli yolları hakkında daha fazla öğrendikten sonra, bir daha az sıkı bir ifadesi iyi olacağına karar verdik. Bu adresler mermi, borular, ve yeni satır ile gösteren edilmiştir. Belki aşağıdaki iletişim bir ifade iyi olurdu:

[numbers][anything]["washington"][anything][DC|D.C.][anything][five numbers]

Görünüşe göre bu yol çok gevşek. Ben bir şey bir kaç karekter izin vererek sadece ilgileniyorum zaman anything blokları, paragraflarda getiriyorlardı.

Şimdiye kadar (bu çoğu sadece bir kaçıdır) aşağıda bulunan eşleşen adresler de başarısız oldum

5 Cevap

EDIT: ilk sayı kümesinden ve 'washington' arasında [şey] veri biraz daha kısıtlayıcı düzgün çalışması için olması gerekir gibi görünür. Iyi, sayılar biz adreslerinden birinin başlangıcını sınırlandırmak için kullanmak ne gibi [şey] bölümünde, herhangi bir rakam içermemelidir. Bu bize verdi üç web siteleri için çalışır.

Ben iyi ilk adım tüm HTML etiketleri dışarı şerit ve 'değiştirmek olacağını söyleyebilirim karakter varlık:

$input = strip_tags($input);
$input = preg_replace("/ /"," ",$input);

adresleri (yakın) maç sonra size belirtilen biçim, yapın:

$results= array();
preg_match("/[0-9]+\s+[^0-9]*?\s+washington,?\s*D\.?C\.?[^0-9]+[0-9]{5}/si",$input,$results);
foreach($result[0] as $addr){
    echo "$addr<br/>";
}

Bu sağlanan üç örnekler için çalışır, ve $results[0] bulunan adreslerin her içermelidir.

Bu sayılar en yakın 'Washington, DC' adresi başlangıcını işaretlemek için varsayar çünkü adres, bir 'Apartman # 2' ya da benzerleri vardır Ancak, bu, örneğin, çalışmaz.

Aşağıdaki komut dosyası test vakalarının her maçlar:

<?php
    $input = "
        1433&nbsp;Longworth House Office Building Washington,  D.C. 20515
         332 Cannon HOB                      Washington   DC   20515
        1641 LONGWORTH HOUSE OFFICE BUILDING WASHINGTON,  DC   20515
        1238 Cannon H.O.B.
        Washington, DC 20515
        8293 Longworth House Office Building • Washington DC • 20515
        8293 Longworth House Office Building | Washington DC | 20515
    ";
    $input = strip_tags($input);
    $input = preg_replace("/&nbsp;/"," ",$input);

    $results= array();
    preg_match_all("/[0-9]+\s+[^0-9]*?washington,?\s*D\.?C\.?[^0-9]*?[0-9]{5}/si",$input,$results);
    foreach($results[0] as $addr){
        echo "$addr<br/>";
    }

Araçları ve bunu yapmak için inşa edilmiştir API vardır. Örneğin, one that works quite well is LiveAddress by SmartyStreets. Bunu geliştirmeye yardımcı, ve bu yüzden bazı ağrı hissediyorum ... Burada söz sağlanan numuneden çıkış bulunuyor:

enter görüntü açıklaması here

İşte CSV çıktı:

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,4,69,"1433&nbsp;Longworth House Office Building Washington, D.C. 20515",Y,0,,1433 Longworth House Office Building Washington D,,Washington DC 20515-0001,Washington,DC,20515,District of Columbia,AAU1,205150001330,,,,Y,38.89106,-77.01132,Zip5,Residential,S,,AL,Q#X#
2,75,134,332 Cannon HOB Washington DC 20515,Y,0,,332 Cannon Hob,,Washington DC 20515-3226,Washington,DC,20515,District of Columbia,AAU1,205153226996,,,,Y,38.89106,-77.01132,Zip5,Residential,H,Y,AL,H#Q#
3,139,199,"1641 LONGWORTH HOUSE OFFICE BUILDING WASHINGTON, DC 20515",Y,0,,1641 Longworth House Office Building,,Washington DC 20515-0001,Washington,DC,20515,District of Columbia,AAU1,205150001411,,,,Y,38.89106,-77.01132,Zip5,Residential,S,,AL,Q#X#
4,204,247,"1238 Cannon H.O.B.
Washington, DC 20515",Y,0,,1238 Cannon H O B,,Washington DC 20515-0001,Washington,DC,20515,District of Columbia,AAU1,205150001385,,,,Y,38.89106,-77.01132,Zip5,Residential,S,,AL,Q#X#
5,252,316,8293 Longworth House Office Building • Washington DC • 20515,Y,0,,8293 Longworth House Office Building,,Washington DC 20515-0001,Washington,DC,20515,District of Columbia,AAU1,205150001934,,,,Y,38.89106,-77.01132,Zip5,Residential,S,,AL,Q#X#
6,321,381,8293 Longworth House Office Building | Washington DC | 20515,Y,0,,8293 Longworth House Office Building,,Washington DC 20515-0001,Washington,DC,20515,District of Columbia,AAU1,205150001934,,,,Y,38.89106,-77.01132,Zip5,Residential,S,,AL,Q#X#

Yaklaşık 2 saniye sürdü. Bu API bir noktaya kadar kullanım için ücretsiz ve bunun gibi diğerleri olabilir; Ben bunu kendi regex (: Bu kod arkasında düzenli ifadeler dayalı değil ipucu) yazmaktan daha iyi olacağını garanti ... sizin için en iyi seçenek bulmak için biraz etrafa yapmak için teşvik ediyoruz.

EDIT:

Bahsettiğiniz sitelere baktıktan sonra, ben aşağıdaki çalışması gerektiğini düşünüyorum. Eğer $page, o zaman kullanabilirsiniz adında bir değişken sürünerek sayfanın içeriğini sahip olduğunu varsayarsak

$subject = strip_tags($page)

sayfadaki tüm HTML biçimlendirme kaldırmak; sonra regex uygulamak

(\d+)\s*(.*?)\s*washington.{0,5}(DC|D.C.).{0,5}(\d{5})

RegexBuddy (PHP bilmiyorum) Bunun için şu kodu üretir:

if (preg_match('/(\d+)\s*(.*?)\s*washington.{0,5}(DC|D.C.).{0,5}(\d{5})/si', $subject, $regs)) {
    $result = $regs[0];
} else {
    $result = "";
}

$regs[1] daha sonra benzeri ilk yakalama Pars (sayılar) içeriğini içeren, ve olacaktır.

Dot maç satırsonu yapmak için, ve regex harf duyarsız yapmak için /si düzenleyiciler kullanımına dikkat edin.

Sen benim için çok net değil soru, ama ben doğru anladım, ben telefon numarası Washington eşleşen eğer ya da bunların herhangi bir kelime "Washington" olup olmadığını kontrol o p etiketlerini maç için bir DOM ayrıştırıcı kullanmak ve sanırım alanı.

Bu regex giriş dizesi içerebilir ne yönelik daha esnek bir yaklaşım getiriyor. "Washington, DC" kısmı içine kodlanmış olmamıştır. Adreslerinin farklı bölümleri ayrı ayrı yakalanır, tüm adres $matches[0] yakalanır.

$input = strip_tags($input);
preg_match('/
(\d++)    # Number (one or more digits) -> $matches[1]
\s++      # Whitespace
([^,]++), # Building + City (everything up until a comma) -> $matches[2]
\s++      # Whitespace
(\S++)    # "DC" part (anything but whitespace) -> $matches[3]
\s++      # Whitespace
(\d++)    # Number (one or more digits) -> $matches[4]
/x', $input, $matches);