Как определить, что в базе указана Москва при разных вариантах написания
Что проверяют
Умеете ли вы строить нормализацию текста, а не перечислять варианты регуляркой. Интервьюер ждёт, что вы учтёте регистр, «ё», латинские буквы-двойники, транслит и опечатки, и не спутаете Москву с Московской областью. Следом спрашивают, как сделать то же на стороне базы для миллионов строк.
Как отвечать
Опишите конвейер нормализации, который одинаково применяется к данным и к эталону:
- регистр и пробелы:
s.strip(), схлопывание пробелов черезre.sub(r"\s+", " ", s), затемcasefold(), он надёжнееlower()для Юникода; - Юникод:
unicodedata.normalize("NFKC", s), замена «ё» на «е», удаление знака ударения U+0301; - гомоглифы: латинские a, o, c, e, p, x внутри кириллического слова заменить таблицей
str.maketrans. Иначе «Mосква» с латинской M не совпадёт ни с чем; - служебные слова: убрать «г.», «город», «гор.»;
- словарь синонимов: «мск», «moscow», «moskva» сводятся к одному ключу. Транслит проще держать списком, чем вычислять;
- опечатки:
rapidfuzz.process.extractOne(name, cities, score_cutoff=85)против справочника городов, а не против одного слова «москва». Тогда «Моска» уйдёт к Москве, а не к первому попавшемуся похожему слову.
На стороне PostgreSQL то же делают расширения unaccent и pg_trgm: функция similarity() и GIN-индекс по триграммам находят похожие строки без выгрузки таблицы в Python.
Главный вывод стоит сказать вслух: разовая чистка лечит симптом. Правильно хранить city_id из справочника, а свободный текст нормализовать при вводе, например через подсказки в форме.
Где спотыкаются
Пишут регулярку со списком написаний или ищут подстроку моск. Первое не покрывает новые варианты, второе ловит «Московскую область» и «Москворечье».
Убирают все диакритики через NFD и фильтр по категории Mn. Вместе с ударением пропадает кратка, и «й» превращается в «и», ломая другие названия.
Включают нечёткое сравнение без порога или сравнивают только с одним эталоном. Короткие названия похожи друг на друга, и в Москву попадают чужие города.