Сравнение адресов в информационных системах — одна из наиболее трудоемких задач. Проблема заключается в отсутствии жесткого стандарта записи: одна и та же локация может быть записана как "3-й квартал Капотни" или "Капотня 3-й кв-л". Разберем пошагово, как реализовать надежный механизм сопоставления таких данных в среде 1С, используя как встроенные средства платформы, так и внешние алгоритмы.
Самый простой и логичный способ, который приходит на ум — это приведение обеих строк к некоему единому "каноническому" виду перед сравнением. Рассмотрим, из каких этапов должен состоять этот процесс, чтобы минимизировать ошибки.
Во-первых, выполним очистку строк. Нам необходимо избавиться от лишних знаков препинания, привести текст к нижнему регистру и заменить специфические символы (например, "ё" на "е"). Во-вторых, крайне важно обработать сокращения. Для этого создадим таблицу соответствий, где "ул" станет "улица", "кв-л" — "квартал" и так далее. Однако, как показывает практика, лучше идти от обратного: удалять типы адресных объектов (стоп-слова), оставляя только значимую часть.
Проанализируем алгоритм сортировки слов (токенов):
Посмотрим на пример реализации такой функции на языке 1С:
Функция ПодготовитьАдресДляСравнения(Знач ВходнаяСтрока)
// Приведение к нижнему регистру и замена ё
Стр = НРег(СтрЗаменить(ВходнаяСтрока, "ё", "е"));
// Удаление спецсимволов
Разделители = ".,-()/";
Для Индекс = 1 По СтрДлина(Разделители) Цикл
Стр = СтрЗаменить(Стр, Сред(Разделители, Индекс, 1), " ");
КонецЦикла;
// Разбиение на слова
МассивСлов = СтрРазделить(Стр, " ", Ложь);
// Список стоп-слов (сокращений)
СтопСлова = "ул,улица,дом,д,корп,корпус,стр,строение,кв,квартира,квл,квартал";
РезультатМассив = Новый Массив;
Для Каждого Слово Из МассивСлов Цикл
Слово = СокрЛП(Слово);
Если ЗначениеЗаполнено(Слово) И Найти(СтопСлова, Слово) = 0 Тогда
РезультатМассив.Добавить(Слово);
КонецЕсли;
КонецЦикла;
// Сортировка токенов
РезультатМассив.Сортировать();
Возврат СтрСоединить(РезультатМассив, " ");
КонецФункции
После такой обработки обе строки "Капотня 3-й кв-л" и "3-й квартал Капотни" превратятся в нечто похожее на "3 капотня". Сравнение таких строк даст положительный результат.
Метод N-грамм является одним из самых мощных инструментов нечеткого сравнения строк. Его суть заключается в разбиении строки на пересекающиеся последовательности символов длиной N. Обычно используют биграммы (2 символа) или триграммы (3 символа).
Выясним, почему это работает. Если мы сравним строки "Капотня" и "Копотня", классическое сравнение скажет "Ложь". Но если мы разобьем их на триграммы:
Для "Капотня": "кап", "апо", "пот", "отн", "тня".
Для "Копотня": "коп", "опо", "пот", "отн", "тня".
Мы увидим, что 3 из 5 триграмм совпадают. Это позволяет вычислить коэффициент сходства (индекс Соренсена или коэффициент Жаккара). Для адресов этот метод хорош тем, что он устойчив к опечаткам и небольшим изменениям в окончаниях слов.
Проанализируем ситуацию: если в одном источнике написано "Капотня", а в другом "Капотнинский", метод N-грамм все равно покажет высокую степень сходства, в отличие от простого сравнения слов.
Этот алгоритм вычисляет минимальное количество операций вставки, удаления и замены символов, необходимых для превращения одной строки в другую. В 1С этот алгоритм часто реализуют для поиска дублей контрагентов.
Для сравнения длинных адресов этот метод стоит применять с осторожностью, так как перестановка целых слов (как в примере автора темы) резко увеличивает "расстояние", хотя по сути адрес один и тот же. Поэтому расстояние Левенштейна лучше использовать как финальный этап проверки для отдельных слов, в которых подозревается опечатка.
Мало кто знает, что встроенный в 1С ПолнотекстовыйПоиск можно использовать для сопоставления данных. Механизм ППП уже умеет работать с морфологией русского языка (понимает формы слов) и допускает поиск с определенным порогом нечеткости.
Схема работы может быть следующей: мы временно записываем эталонные адреса в индексируемый регистр сведений, а затем программно выполняем поиск "грязного" адреса через ПолнотекстовыйПоиск.СоздатьСписок(). Система сама ранжирует результаты по релевантности, учитывая перестановки слов и частичные совпадения.
Самый надежный профессиональный подход — это отказ от сравнения строк в пользу сравнения идентификаторов. В России стандартом является ГАР (Государственный адресный реестр), пришедший на смену ФИАС.
Рассмотрим по шагам, как это реализовать:
Если оба адреса успешно распознаны и указывают на один и тот же дом, их GUID будут идентичны, независимо от того, как они были записаны в исходных строках. Это снимает все вопросы с сокращениями, порядком слов и опечатками.
Выбор конкретного метода зависит от объема данных и требований к точности:
Комбинированный подход часто дает наилучший результат: сначала пробуем прямое сравнение нормализованных строк, а для тех записей, где совпадение не найдено, запускаем более "тяжелые" алгоритмы нечеткого поиска или обращаемся к внешним API.