Separare il nome della via dal numero civico

Sto cercando di separare i nomi delle strade dai numbers civici che hanno questi templates:

  1. "via 12" — nome: via, numero: 12
  2. "street12" — nome: via, numero: 12
  3. "via 12a" — nome: via, numero: 12a
  4. "street12a" — nome: via, numero: 12a

Qual è la regex per get il nome della via e la regex per get il numero civico in php e python?

Nota: il numero è sempre dopo il nome della via, quindi suppongo che dovrebbe ridurlo.

Grazie.

Prova questo come vedere se funziona per voi:

 $subjects = arrays( "street 12", "street12", "street 12a", "street12a" ); foreach( $subjects as $subject ) { if ( preg_match('/([^\d]+)\s?(.+)/i', $subject, $result) ) { var_dump( $result ); } } die_r( $result ); 

L'unica parte di cui hai bisogno è questa:

 // Find a match and store it in $result. if ( preg_match('/([^\d]+)\s?(.+)/i', $subject, $result) ) { // $result[1] will have the steet name $streetName = $result[1]; // and $result[2] is the number part. $streetNumber = $result[2]; } 

Suggerirei che il modo migliore per determinare quando inizia il numero è quando si preme una cifra. Quindi, useresti

 preg_match('/^([^\d]*[^\d\s]) *(\d.*)$/', $address, $match) 

Esempi:

 'Bubbletown 145' => 'Bubbletown', '145' 'Circlet56a' => 'Circle', '56a' 'Bloomfield Avenue 68' => 'Bloomfield Avenue', '68' 'Quibbit Ave 999a' => 'Quibbit Ave', '999a' 'Singletown551abc' => 'Singletown', '551abc' 

Probabilmente sarà meglio per te considerare come vuoi gestire i casi limite, quindi scrivere un test unitario per testare la tua propria function Regex.

In generale, gli indirizzi non sono sempre così puliti. Soprattutto se questi dati provengono direttamente dagli utenti, devi considerare che non tutti hanno un indirizzo così standard. Ci sono caselle postali, routes rurali, 31 1/2 s, suite, tonnellate di variazioni sui tipi di strada (strade, strade, circoli, tribunali, ecc., Oltre a tutte le loro abbreviazioni). Spazi in nomi di strade, ipens nel numero civico, la complessità degli indirizzi è molto facile da sottovalutare. Mescola il potenziale per gli indirizzi non statunitensi e la complessità aumenta esponenzialmente.

Questa gigantesca function cerca di dare un senso a tutto ciò (alless per quanto riguarda gli US Post): http://codepad.org/pkTdUDL6 Avevo questa function che mi dava da fare, quindi potrebbe aver bisogno di modifiche o elaborazioni. Se non altro, dovrebbe darvi un'idea del task che si deve affrontare quando si cerca di rendere sani i dati degli indirizzi degli utenti.

Questo rende anche allettante dividere il numero civico, il nome della via e il tipo di strada in campi separati. Se la precisione degli indirizzi di analisi è fondamentale per la progettazione del sistema, è consigliabile considerarla; per esempio, i sisthemes immobiliari dovrebbero avere questo livello di granularità per questi dati. Se il tuo caso d'uso non si basa in modo critico sulla capacità di analizzare accuratamente questi dati, allora non suggerirei di presentare un utente con tutti quei campi aggiuntivi. Prendi il loro indirizzo mentre lo danno, prova a ripulirlo e anticipa alcune incoerenze nel resto del progetto del tuo sistema.

Supponendo che possa esserci solo una lettera finale,

 if (preg_match('/^(.+) *(\d+[az]?)$/', $address, $match)) { list($street, $number) = $match; } 

L'analisi degli indirizzi stradali può diventare sgradevole, molto veloce. Il modo più affidabile e privo di preoccupazioni è quello di utilizzare un servizio in grado di risolvere i componenti dell'indirizzo in base al codice a barre del punto di consegna completo (codice postale a 9 cifre + punto di consegna a 3 cifre).

Lavoro per un'azienda di verifica degli indirizzi, SmartyStreets e abbiamo un'API in grado di analizzare questi componenti per te. Vedi questo esempio . Solo una semplice richiesta GET e hai un risultato JSON con tutti i componenti dell'indirizzo analizzati per te.

Aggiornamento : SmartyStreets ora fornisce la verifica dell'indirizzo internazionale .

Può essere vecchio, ma riferendosi al commento di Pekka vorrei usare la regex seguente nel codice b01:

 /(.+?)\s?([\d]+[\D]*)$/i 

così il codice completo sarebbe

 // Find a match and store it in $result. if ( preg_match('/(.+?)\s?([\d]+[\D]*)$/i', $subject, $result) ) { // $result[1] will have the steet name $streetName = $result[1]; // and $result[2] is the number part. $streetNumber = $result[2]; } 

Questo seleziona l'ultimo numero che si verifica includendo i seguenti caratteri (ad es. 15F / 15 F) mentre rileva ancora le strade inclusi i numbers (come 5th Avenue 123, Straße des 17. Juni 123)