Отдельное название улицы с номера улицы

Я пытаюсь отделить названия улиц от номеров улиц, которые имеют следующие шаблоны:

  1. «улица 12» — название: улица, номер: 12
  2. "street12" — имя: улица, номер: 12
  3. «улица 12а» — название: улица, номер: 12а
  4. "street12a" — название: улица, номер: 12а

Что такое регулярное выражение, чтобы получить название улицы, и регулярное выражение, чтобы получить номер улицы в php и python?

Примечание. Номер всегда стоит после названия улицы, поэтому я предполагаю, что это должно сократить его.

Благодарю.

Попробуйте это, как посмотреть, работает ли он для вас:

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

Единственная часть, в которой вы нуждаетесь, такова:

 // 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]; } 

Я бы предположил, что лучший способ определить, когда начинается число, – это когда вы нажимаете цифру. Таким образом, вы

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

Примеры:

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

Вероятно, вам будет лучше рассмотреть вопрос о том, как вы хотите обработать граничные случаи, а затем написать единичный тест для проверки собственной функции Regex.

Вообще говоря, адреса не всегда чисты. Особенно, если эти данные поступают прямо от пользователей, вы должны учитывать, что не каждый имеет такой стандартный адрес. Есть PO-боксы, сельские маршруты, 31 1/2 с, апартаменты, тонны вариаций на улицах (Road, Street, Circle, Court и т. Д. И т. Д., А также все их сокращения). Пространства в названиях улиц, подстрочные номера в домах, сложность адресов очень легко недооценивать. Смешайте потенциал для неамериканских адресов, и сложность возрастает экспоненциально.

Эта гигантская функция пытается разобраться во всем этом (по крайней мере, в отношении Почты США): http://codepad.org/pkTdUDL6 У меня была эта функция, но она может понадобиться для настройки или разработки. Если ничего другого, это должно дать вам представление о задаче, с которой приходится сталкиваться при попытке сделать данные пользовательских адресов разумными.

Это также заставляет задуматься разбить номер дома, название улицы и тип улицы на отдельные поля. Если точность парсинга адресов имеет решающее значение для дизайна вашей системы, вы можете ее рассмотреть; системы недвижимости, например, должны были бы иметь этот уровень детализации для этих данных. Если ваш случай использования не критически полагается на способность точно анализировать эти данные, я бы не предложил представить пользователю все эти дополнительные поля. Просто возьмите их адрес, как они его дают, попробуйте очистить его и предвидеть некоторые несоответствия в остальной части вашей системы.

Предполагая, что может быть только одна последняя буква,

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

Разбор уличных адресов может стать неприятным, очень быстрым. Самым надежным, беспроблемным способом является использование службы, которая может разрешать компоненты адреса на основе штрих-кода полной доставки (9-значный почтовый индекс + 3-значный пункт доставки).

Я работаю в компании по проверке адресов, SmartyStreets, и у нас есть API, который может анализировать эти компоненты для вас. См. Этот образец . Просто простой запрос GET, и у вас есть результат JSON, в котором проанализированы все компоненты адреса.

Обновление : теперь SmartyStreets обеспечивает проверку международного адреса .

Может быть старым, но, ссылаясь на комментарий от Pekka, я буду использовать следующее регулярное выражение в коде b01:

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

поэтому полный код будет

 // 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]; } 

Это выбирает последнее встречное число, включая следующие символы (например, 15F / 15 F), при этом все еще обнаруживает улицы, включая номера (как 5-й Ave 123, Straße des 17. Juni 123)