Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP Puzzles. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель PHP 5 / 6 (3 издание). Авторы: Кузнецов М.В., Симдянов И.В. PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В. Объектно-ориентированное программирование на PHP. Авторы: Кузнецов М.В., Симдянов И.В. MySQL на примерах. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум Регулярные Выражения

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Как найти номер дома и улицы в адресе?
 
 автор: terra nova   (13.06.2013 в 10:33)   письмо автору
 
 

До конца не могу составить запрос. Допусти, что номер дома - это цифры - 1-3 символа D {1,3}
Затем влево и вправо искать не меньше 4-х букв подряд - это название улицы.
(?<=[a-zA-Z]{4,})(?=[a-zA-Z]{4,})
Между номером дома и названием улицы может быть любая комбинация
точек, тире, слешей, пробелов и цифр, букв до трех символов в длину. Например "Strada Roma c/da, - 12, 093 903"

Как найти номер дома и улицы в адресе?

  Ответить  
 
 автор: cheops   (13.06.2013 в 22:18)   письмо автору
 
   для: terra nova   (13.06.2013 в 10:33)
 

Хм... адрес совершенно произвольный? Тогда могут быть проблемы, так как у дома может быть несколько корпусов, а некоторые дома расположены на пересечении двух улиц и их номера пишутся через дробь (номер на одной и на другой улице).

  Ответить  
 
 автор: Sfinks   (14.06.2013 в 10:24)   письмо автору
 
   для: cheops   (13.06.2013 в 22:18)
 

А еще могут быть цифры в названии улицы: 30 лет победы, 7-ая гвардейская и т.п.

  Ответить  
 
 автор: terra nova   (14.06.2013 в 14:44)   письмо автору
 
   для: Sfinks   (14.06.2013 в 10:24)
 

Ага, могут. Поэтому надо будет еще и вручную смотреть и отлаживать, но у меня не получается построить регулярку. Как указать, что между 1-3 цифрами и 4 и больше буквами будут всякие пробельные символы, знаки препинания, и буквы меньше 4 символов длиной?

  Ответить  
 
 автор: Sfinks   (14.06.2013 в 16:47)   письмо автору
 
   для: terra nova   (14.06.2013 в 14:44)
 

Сейчас немного некогда, постараюсь попозже вам помочь....
Только вот вы уверены, что:
> между 1-3 цифрами и 4 и больше буквами будут всякие пробельные символы, знаки препинания, и буквы меньше 4 символов длиной?
В вашем же примере:
Strada Roma c/da, - 12, 093 903
между ними 4 символа.

  Ответить  
 
 автор: Sfinks   (15.06.2013 в 16:20)   письмо автору
 
   для: terra nova   (13.06.2013 в 10:33)
 

Вообще, уже сел писать РВ, и понял, что я сам не могу понять что в приведенном примере есть улица, а что номер дома.
Не говоря уж о том, что объяснить это компьютеру.

> не меньше 4-х букв подряд - это название улицы
Т.е. пробелов в названиях улиц быть не может?
Т.е. в примере улица - это Roma?

> Между номером дома и названием улицы может быть любая комбинация
> точек, тире, слешей, пробелов и цифр, букв до трех символов в длину

и
> номер дома - это цифры - 1-3 символа
Под номер дома с таким описанием подходит и 12, и 093, и 903
Как правильно? И на каком основании нужно сделать этот вывод?

  Ответить  
 
 автор: terra nova   (17.06.2013 в 13:40)   письмо автору
 
   для: Sfinks   (15.06.2013 в 16:20)
 

Via Livorno 146, 95021 Ачитрецца
Via Nazionale, 147 - 98030 Taormina Mare (ME)
C/da Falconara, Ното, Италия
Lungomare G.Giardina, 90015 Чефалу

Выше я привел 4 случайно выбранных адреса. У некоторых нет номера дома или даже километра шоссе. У некоторых только почтовый индекс.
Ищу любое первое число: preg_match('/(\d+)/is',$in,$pockets);
Если числа нет, перехожу к первым a-z{4,}
Если число есть, то ищу слева a-z{4,}

  Ответить  
 
 автор: Sfinks   (17.06.2013 в 13:57)   письмо автору
 
   для: terra nova   (17.06.2013 в 13:40)
 

Так и не нужно все это пытаться запихнуть в одно РВ.
Совместите строковые функции для определения типа адреса (с номером, без номера) и уже потом оперируйте простыми РВ в пределах выполненного условия.

  Ответить  
 
 автор: terra nova   (17.06.2013 в 14:02)   письмо автору
 
   для: Sfinks   (17.06.2013 в 13:57)
 

Не могу понять в чем ошибка:
preg_match('/(a-z{4,})^(a-z{4,})(\d+)/s',$in,$pockets);

В первых скобках - улица
Потом всякий мусор, сокращения и т. д.
Потом номер

Ничего не находит :-(

  Ответить  
 
 автор: Sfinks   (17.06.2013 в 16:55)   письмо автору
 
   для: terra nova   (17.06.2013 в 14:02)
 

'/((?<=^|[^a-z])[a-z]{4,})[^a-z]*?(\d+)/'
должно быть так кажись....

  Ответить  
 
 автор: terra nova   (17.06.2013 в 17:06)   письмо автору
 
   для: Sfinks   (17.06.2013 в 16:55)
 

Сработало! Спасибо!
/((?<=^|[^a-z])[a-z]{4,})[^a-z]*?(\d+)/is

Понять бы еще логику. Вот "поиск влево" понимаю: ?<=
Вот это не понял: ^|
"Искать 4 или больше буквы" понял: [a-z]{4,}
Скобки круглые понял - это чтобы наполнить первую переменную, а потом вторую. Сначала улица, а потом номер дома.
А вот зачем вопросительный знак?

  Ответить  
 
 автор: Sfinks   (17.06.2013 в 17:11)   письмо автору
 
   для: terra nova   (17.06.2013 в 17:06)
 

/((?<=^|[^a-z])[a-z]{4,})[^a-z]*?(\d+)/
перевожу:
[a-z]{4,} -4 и более буквы
(?<=) -перед которыми
^(начало строки) |(или) [^a-z](не буква)
затем
[^a-z]*? - правильнее, кстати [^a-z]+? -хотя бы одна не буква с "не жадным" поиском, т.е. ближайшее совпадение со следующим шаблоном идет уже в следующий шаблон, который гласит:
(\d+) -одна и более цифр.

  Ответить  
 
 автор: terra nova   (17.06.2013 в 17:27)   письмо автору
 
   для: Sfinks   (17.06.2013 в 17:11)
 

Спасибо большое! А до жадности квантификаторов я просто еще не дочитал.

  Ответить  
 
 автор: terra nova   (18.06.2013 в 11:01)   письмо автору
 
   для: Sfinks   (17.06.2013 в 17:11)
 

Забыл сказать, что в базе данных вместо пробелов почему-то попадаются символы псевдографики
Попробовал специальным выражением и добавил |[^:graph:]+?
/((?<=^|[^a-z])[a-z]{4,})[^a-z]+?|[^:graph:]+?(\d+)/is
Но теперь какую-то ерунду выдает. Не подскажите в чем ошибка?

http://www.regexpr.ru/?pattern=%2F%28%28%3F%3C%3D%5E%7C%5B%5Ea-z%5D%29%5Ba-z%5D%7B4%2C%7D%29%5B%5Ea-z%5D%2B%3F%28%5Cd%2B%29%2Fis&subject=Via+Garibaldi+126%2C+%CC%E5%F1%F1%E8%ED%E0%2C+%C8%F2%E0%EB%E8%FF

  Ответить  
 
 автор: Sfinks   (18.06.2013 в 11:31)   письмо автору
 
   для: terra nova   (18.06.2013 в 11:01)
 

>Забыл сказать, что в базе данных вместо пробелов почему-то попадаются символы псевдографики
Обработайте перед проверкой функцией strtr():
$addr = strtr($addr, "список символов, которые нужно заменить", "тут столько пробелов, сколько символов во втором аргументе");


http://www.regexpr.ru/?pattern=%2F%28%28%3F%3C%3D%5E%7C%5B%5Ea-z%5D%29%5Ba-z%5D%7B4%2C%7D%29%5B%5Ea-z%5D%2B%3F%28%5Cd%2B%29%2Fis&subject=Via+Garibaldi+126%2C+%CC%E5%F1%F1%E8%ED%E0%2C+%C8%F2%E0%EB%E8%FF
- это что за ссылка? По ней все вроде работает.

  Ответить  
 
 автор: terra nova   (18.06.2013 в 12:18)   письмо автору
 
   для: Sfinks   (18.06.2013 в 11:31)
 

Я случайно дал не ту ссылку. Вот правильная. Здесь проверка регулярного выражения выдает странный результат:
http://www.regexpr.ru/?pattern=%2F%28%28%3F%3C%3D%5E%7C%5B%5Ea-z%5D%29%5Ba-z%5D%7B4%2C%7D%29%5B%5Ea-z%5D%2B%3F%7C%5B%5E%3Agraph%3A%5D%2B%3F%28%5Cd%2B%29%2Fis&subject=New+street%2C+1

Проблема в том, что спецсимволы попадаются очень редко, я сейчас их не найду. Проще написать с использованием [:graph:]

  Ответить  
 
 автор: terra nova   (18.06.2013 в 12:25)   письмо автору
 
   для: Sfinks   (18.06.2013 в 11:31)
 

И еще проблема. Если перед номером трассы не стоит названия улицы, то поиск ничего не дает.
Сейчас подумаю как сделать поиск и вправо тоже

Пример:
Ss.113 Km 338, Calatafimi, Калатафими

  Ответить  
 
 автор: terra nova   (18.06.2013 в 12:27)   письмо автору
 
   для: terra nova   (18.06.2013 в 12:25)
 

А еще некоторые пишут без пробела
Via Nazionale Ss113, Карония

Хотел написать запрос, чтобы возвращал название местности идущее после цифр, а получилось найти перед цифрами :-(

/((?<=^|[^a-z])[a-z]{4,})|(?=[a-z]{4,})*?(\d+)/is

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования