Использование RegExp для причесывания адресов

Создание карты участковых избирательных комиссий
Ответить
bolotoved
Гуру
Сообщения: 920
Зарегистрирован: 30 дек 2008, 14:11
Статьи: 4
Проекты: 1
Репутация: 235
Откуда: Ханты-Мансийск
Контактная информация:

Использование RegExp для причесывания адресов

Сообщение bolotoved » 24 авг 2013, 18:27

Дана строка:

Код: Выделить всё

src_txt = u'МБОУ лицей №1, ул. Энтузиастов 61а, Школа №2, ул. 30 лет Победы, д.39/1, ул. Розы Люксембург, 1'


Из этой строки нужно извлечь адреса, где перед номером дома не стоит "д.", т.е. запрос должен нам дать:

Код: Выделить всё

ул. Энтузиастов 61а
ул. Розы Люксембург, 1
Что-то никак не могу сообразить как тут правильно применить lookbehind, и вообще его ли надо применять?

ericsson
Гуру
Сообщения: 3205
Зарегистрирован: 27 июл 2009, 19:26
Репутация: 687
Ваше звание: Вредитель полей

Re: Использование RegExp для причесывания адресов

Сообщение ericsson » 24 авг 2013, 19:39

Сначала разобрать на строки по запятым, а потом использовать negative lookahead в духе (?!\.д) в середине шаблона?

bolotoved
Гуру
Сообщения: 920
Зарегистрирован: 30 дек 2008, 14:11
Статьи: 4
Проекты: 1
Репутация: 235
Откуда: Ханты-Мансийск
Контактная информация:

Re: Использование RegExp для причесывания адресов

Сообщение bolotoved » 24 авг 2013, 20:04

Код: Выделить всё

src_txt = u'МБОУ лицей №1, ул. Энтузиастов 61а, Школа №2, ул. 30 лет Победы, д.39/1, ул. Розы Люксембург, 1'
street_pattern = u'ул\..[^,]*? .*?\d'
streets = re.findall(street_pattern, src_txt)
result = [''.join(x) for x in streets]
result = '\n'.join(result)
print result


дает результат:

Код: Выделить всё

ул. Энтузиастов 6
ул. 30 лет Победы, д.3
ул. Розы Люксембург, 1
У меня ступор: как используя lookaround модифицировать u'ул\..[^,]*? .*?\d', чтобы обрезать ул. 30 лет Победы, д.3
Видимо, я как-то не очень улавливаю логику использования lookaround...
Если бы это удалось, я бы использовал re.sub() и проставил недостающие д. там где нужно.

bolotoved
Гуру
Сообщения: 920
Зарегистрирован: 30 дек 2008, 14:11
Статьи: 4
Проекты: 1
Репутация: 235
Откуда: Ханты-Мансийск
Контактная информация:

Re: Использование RegExp для причесывания адресов

Сообщение bolotoved » 26 авг 2013, 21:41

Задача: проставить "д." там где не хватает в строке c помощью модуля Python RE

МБОУ лицей №1, ул.Энтузиастов 61а
Школа №2, ул. 30 лет Победы, д.39/1, (актовый зал)
ул.Розы Люксембург, 1, общежитие
ул. Ленина, д.5

Решение:

Код: Выделить всё

src_txt = u'МБОУ лицей №1, ул. Энтузиастов 61а\nШкола №2, ул. 30 лет Победы, д.39/1, (актовый зал)\nул. Розы Люксембург, 1, общежитие\nул. Ленина, д.5'
street_pattern = u'(ул\\..)(.*?[, ])(.*?)([\\d])(?<!д\\..)(?<!д\\...)(?<!д\\....)(?<!д\\.....)(?<!д\\......)'
streets = re.sub(street_pattern, u'\\1\\2\\3д.\\4', src_txt, re.U)
print streets


Воспользуемся ф-ей re.sub для поиска и замены фрагментов текста с использованием регулярных выражений.
В скобках в паттерне поиска идут поисковые фрагменты, которые нумеруются с начала паттерна к концу:
(ул\\..) - первый поисковый фрагмент
(.*?[, ]) - второй поисковый фрагмент (ищет фрагмент строки от ул. до первого пробела или запятой)
(.*?)([\\d]) - 3-й и 4-й поисковые фрагменты (поиск от конца предыдущего фрагмента до первой цифры)
(?<!д\\..) - исключение из результатов поиска строки оканчивающейся на д.после которой идет произвольный символ (чтобы исключить вар. ул. 30 лет Победы, д.3)
(?<!д\\...) - тоже, но после д. - 2 произвольных символа и т.д. (чтобы исключить вар. ул. 30 лет Победы, д.39)

Применяя re.sub вставляем после 3-го фрагмента д. (подстроки где уже стоит д. у нас исключены). Замещающий паттерн будет выглядеть так:
u'\\1\\2\\3д.\\4'

Замечание: поскольку мы имеем дело с кириллицей, чтобы регулярные выражения работали адекватно, необходимо декодировать исходный текст в уникод. В скрипте это сделано с помощью u''.
Также при использовании RE необходимо прямо указать, что регулярные выражения включают уникод: флаг re.U

Результат:

Код: Выделить всё

МБОУ лицей №1, ул.Энтузиастов д.61а
Школа №2, ул. 30 лет Победы, д.39/1, (актовый зал)
ул.Розы Люксембург, д.1, общежитие
ул. Ленина, д.5

Ответить

Вернуться в «УИК ГЕО»