Задание по регулярным выражениям от Егора
Эту задачку придумал мой коллега Егор Симонов. Она используется для обучения стажеров. Одно из условий испытательного срока тестировщика — сдать Егору это задание. А это не так то легко! Егора не проведешь, сдать «ну вот тут не сработает, конечно, зато остальное норм» не пройдет ))
Хорошая задачка с подколками. Сможете ее решить?
Есть набор строк с адресами. Нам эти адреса нужно «почистить», убрать лишнее. Как именно? Смотри в таблице ниже.
Мы должны написать правила замены. Каждое правило замены содержит два обязательных и один опциональный параметр:
regexp — шаблон, регулярное выражение;
replacement — замена, применяется если входная строка удовлетворяет шаблону
exception (опциональный) — запрещающий шаблон, тоже регулярное выражение. Если входная строка подходит по шаблону и одновременно подходит по запрещающему шаблону, замена не применяется;
Правила замены применяются последовательно для входных данных, в том порядке, в котором они указаны.
Делается попытка применить все правила замены для каждой строки, нельзя остановиться в каком-то месте.
Для отладки регулярных выражений можно воспользоваться, например, плагинами Regex
или Regex Tester
в IDEA
, онлайн-проверщиком регулярных выражений (http://myregexp.com, https://regex101.com/) или плагином для eclipse
(для фанатов оного) с того же сайта http://myregexp.com (рекомендую попробовать несколько вариантов).
Входной адрес | Что надо получить | Комментарий |
---|---|---|
140002 ЛЮБЕРЦЫ 2 ОКТЯБРЬСКИЙ ПР 123/4-115 | 140002 ЛЮБЕРЦЫ ОКТЯБРЬСКИЙ ПР 123/4-115 | После названия города может идти цифра, совпадающая с концом индекса. Это номер почтового отделения. Это не адресная информация, надо убрать. |
636450 636450, Г. ТОГУР, УЛ. БЕЛИНСКОГО Д. 6 КВ 2 | 636450, Г. ТОГУР, УЛ. БЕЛИНСКОГО Д. 6 КВ 2 | Дублирование индексов - не смертельно, но нехорошо. Убрать. |
423571 423571 НИЖНЕКАМСК 1 ТАТАРСТАН ВАХИТОВА 51-171 | 423571 НИЖНЕКАМСК ТАТАРСТАН ВАХИТОВА 51-171 | Комбинация первых двух случаев. |
658219 РУБЦОВСК 19 УЛ. ЖЕЛЕЗНОДОРОЖНАЯ 194 | 658219 РУБЦОВСК УЛ. ЖЕЛЕЗНОДОРОЖНАЯ 194 | Номер отделения может состоять из двух цифр. |
622049 НИЖНИЙ ТАГИЛ 49 УРАЛЬСКИЙ ПР 54-252 | 622049 НИЖНИЙ ТАГИЛ УРАЛЬСКИЙ ПР 54-252 | Город - не обязательно одно слово. |
344112 РОСТОВ-НА-ДОНУ 112 УЛ КИЗИТИРИНОВСКАЯ Д 37 3 | 344112 РОСТОВ-НА-ДОНУ УЛ КИЗИТИРИНОВСКАЯ Д 37 3 | Или даже так. |
127543 МОСКВА 543,МОСКВА 543,КОНЕНКОВА 12-32 | 127543 МОСКВА,КОНЕНКОВА 12-32 | Часть с номером отделения может повторяться. |
391112 РЫБНОВСКИЙ РАЙОН, РЫБНОЕ 2 БОЛЬШАЯ 18-33 | 391112 РЫБНОВСКИЙ РАЙОН, РЫБНОЕ БОЛЬШАЯ 18-33 | Может и район быть. |
622049 НИЖНИЙ ТАГИЛ, УРАЛЬСКИЙ ПР 49 252 | 622049 НИЖНИЙ ТАГИЛ, УРАЛЬСКИЙ ПР 49 252 | А тут 49 - номер дома, терять нельзя |
420098 420098 КАЗАНЬ 98 ТАТАРСТАН ЛЕСНАЯ 18 | 420098 КАЗАНЬ ТАТАРСТАН ЛЕСНАЯ 18 | Что-то такое-же уже было. =) |
644103 ОМСК 103 3 МАТЕРИАЛЬНЫЙ ПЕР 45 | 644103 ОМСК 3 МАТЕРИАЛЬНЫЙ ПЕР 45 | Нельзя потерять 3, она относится к улице |
431451 РУЗАЕВКА 11 ШКОЛЬНЫЙ БУЛЬВАР Д 2 Б КВ 27 | 431451 РУЗАЕВКА ШКОЛЬНЫЙ БУЛЬВАР Д 2 Б КВ 27 | Есть и хитрые номера отделений, они состоят из двух цифр (всегда), причём последняя совпадает с последней цифрой индекса, а первая с предпоследней не совпадает. |
666793 УСТЬ-КУТ 13 ИРКУТСКАЯ ОБЛ УЛ ПУШКИНА 113 КВ 65 | 666793 УСТЬ-КУТ ИРКУТСКАЯ ОБЛ УЛ ПУШКИНА 113 КВ 65 | Аналогично. |
347042 БЕЛАЯ КАЛИТВА 2 ЭНГЕЛЬСА 42 КВ. 20 | 347042 БЕЛАЯ КАЛИТВА ЭНГЕЛЬСА 42 КВ. 20 | Нельзя потерять 42 |
344079 РОСТОВ-НА-ДОНУ 79 ПРОФИНТЕРНА 79 КВ,60 | 344079 РОСТОВ-НА-ДОНУ ПРОФИНТЕРНА 79 КВ,60 | Нельзя потерять 79 |
344079 РОСТОВ-НА-ДОНУ 39 ПРОФИНТЕРНА 79 КВ,60 | 344079 РОСТОВ-НА-ДОНУ ПРОФИНТЕРНА 79 КВ,60 | Нельзя потерять 79 |
644011 ПРОЕЗД 7 ТЮКАЛИНСКИЙ, ДОМ 7,ГОРОД ОМСК, 644011 | 644011 ПРОЕЗД 7 ТЮКАЛИНСКИЙ, ДОМ 7,ГОРОД ОМСК | В конце может стоять копия индекса |
141006 МЫТИЩИ 6 ОЛИМПИЙСКИЙ ПР-Т 18, 1410 | 141006 МЫТИЩИ ОЛИМПИЙСКИЙ ПР-Т 18 | Копия может быть не полной, а содержать, например, 4 первых цифры индекса |
141006 МЫТИЩИ 6 ОЛИМПИЙСКИЙ ПР-Т 18, 141 | 141006 МЫТИЩИ ОЛИМПИЙСКИЙ ПР-Т 18 | ...или даже три |
141006 МЫТИЩИ 6 ОЛИМПИЙСКИЙ ПР-Т 18, КВ. 141 | 141006 МЫТИЩИ ОЛИМПИЙСКИЙ ПР-Т 18, КВ. 141 | Но если перед конечной цифрой стоит "КВ.", это квартира |
141006 МЫТИЩИ 6 ОЛИМПИЙСКИЙ ПР-Т 18, КВ 141 | 141006 МЫТИЩИ ОЛИМПИЙСКИЙ ПР-Т 18, КВ 141 | ...или "КВ" |
141006 МЫТИЩИ 6 ОЛИМПИЙСКИЙ ПР-Т 18, КВД 141 | 141006 МЫТИЩИ ОЛИМПИЙСКИЙ ПР-Т 18, КВД | ...а КВД - не квартира =) |
Результирующие адреса могут отличаться от требуемых в таблице, но незначительно. То есть если в эталоне один пробел, а получилось два - это нормально. А вот терять точки и запятые - неправильно. Можно добавлять запятые, но только в правильных местах.
В таблице приведены, скажем так, шаблоны косяков. Не надо закладываться на конкретные цифры. Если при изменении какой-нибудь циферки в адресе, которое подходит по шаблону, правило перестанет работать, это неправильно.
Во избежание дополнительных вопросов будем считать, что нормальные адреса не могут быть похожи на те, которые приведены в задаче. =)
Пример оформления
1. Заменить слово ПЛОХО на слово ХОРОШО, если не содержится подстрока НЕ ТРОГАТЬ или ТАК НАДО:
regexp — ^(.)ПЛОХО(.)$
replacement — $1ХОРОШО$
exception — ^.(НЕ ТРОГАТЬ|ТАК НАДО).$
2. Заменить …
Как проверять себя
Написали список правил
Взяли список исходных адресов, скопировали себе куда-то, в блокнот, например
Применили ко всему списку правило 1
Применили ко всему списку правило 2
...
Применили последнее правило (ко всему списку, уже N раз измененному)
Сверили результат с колонкой «Что надо получить», обращая внимание на комментарии. Ничего не потерялось?
Если потерялось / испортилось, то находим баг в регулярках, исправляем, и повторяем все шаги с самого начала =)