-- 124_deglue_avito_addresses.sql -- #1773 — де-слип номера дома и маркера района/нас.пункта в listings.address (Avito). -- -- ПРОБЛЕМА (прод). Avito-адреса хранят номер дома СЛИПШИМСЯ с маркером района без -- разделителя: «…ул. Евгения Савкова, 29р-н Академический» (номер «29» приклеен к -- «р-н Академический»). Паттерны из данных: «29р-н», «17Ар-н», «35/2р-н», «33с1р-н», -- «44Бр-н». Из-за склейки ломается извлечение номера дома и матчинг «того же дома» -- (41 несматченный avito-листинг по одной улице). -- -- ЧТО ДЕЛАЕТ. Вставляет «, » между токеном номера дома и следующим за ним маркером -- района/нас.пункта без пробела. На ingest то же чинит avito.py::_clean_address; -- этот backfill чистит УЖЕ сохранённые строки на деплое. -- -- ПОЧЕМУ POSIX-ERE без lookahead. Postgres regexp_replace не поддерживает (?=…), -- поэтому маркер фиксируется хвостовой группой \3 = «не кириллица/не цифра или конец» -- (гарантирует, что маркер — целый токен, а не начало слова). Литера дома [А-Яа-яЁё]? -- жадная, но движок обязан затем сматчить целый маркер вплотную — иначе совпадения нет. -- Корпус «сN/кN» требует цифру, поэтому не путается с маркерами «с.» (село) / «к». -- -- Idempotent: regexp_replace на уже-расклеенной строке («29, р-н») — no-op -- (между номером и маркером уже стоит «, »); WHERE отбирает только ещё-слипшиеся -- строки. Под gate _schema_migrations (ровно один раз). -- Apply after: 123_avito_newbuilding_sweep_schedule.sql BEGIN; UPDATE listings SET address = regexp_replace( address, -- \1 = токен номера дома (цифры + опц. литера + опц. корпус/строение) -- \2 = маркер района/нас.пункта -- \3 = хвостовая граница (не буква/цифра или конец строки) '([0-9]+[А-Яа-яЁё]?(/[0-9]+|с[0-9]+|к[0-9]+|корп\.? ?[0-9]+|стр\.? ?[0-9]+)?)' || '(р-?н|мкр\.?|микрорайон|район|г\.|пос\.?|посёлок|поселок|снт|кв-л|квартал|д\.|с\.|пгт)' || '([^А-Яа-яЁё0-9]|$)', '\1, \3\4', 'g' ) WHERE source = 'avito' AND address ~ ('([0-9]+[А-Яа-яЁё]?(/[0-9]+|с[0-9]+|к[0-9]+|корп\.? ?[0-9]+|стр\.? ?[0-9]+)?)' || '(р-?н|мкр\.?|микрорайон|район|г\.|пос\.?|посёлок|поселок|снт|кв-л|квартал|д\.|с\.|пгт)' || '([^А-Яа-яЁё0-9]|$)'); COMMIT;