Разбор неструктурированного адреса — это классическая и одновременно сложная задача для разработчика 1С. Основная трудность заключается в том, что пользователь может ввести данные в произвольном формате: пропустить запятые, допустить опечатки, использовать сокращения или изменить порядок следования элементов (например, сначала город, потом индекс). В данной статье мы подробно разберем, как превратить «грязную» строку в структурированный адрес формата ФИАС/ГАР, используя внутренние инструменты платформы и программные методы.
Если вы работаете в современной конфигурации (УТ 11, БП 3.0, ЗУП 3.1), то в вашем распоряжении уже есть мощный инструмент — подсистема «Адресный классификатор». 1С хранит данные ГАР (Государственного адресного реестра) в специализированных таблицах. Мы можем использовать программный интерфейс модуля РаботаСАдресами для сопоставления строки с базой.
Рассмотрим пример использования функции автоподбора. Система сама попытается проанализировать токены строки и найти наиболее подходящий адрес в справочнике:
// Пример программного обращения к механизмам БСП для поиска адреса
АдреснаяСтрока = "165300, Архангельская обл., Котлас, Маяковского, 2";
ПараметрыПоиска = РаботаСАдресами.ПараметрыАвтоподбора();
ПараметрыПоиска.Текст = АдреснаяСтрока;
ПараметрыПоиска.Количество = 1; // Берем наиболее подходящий вариант
РезультатПоиска = РаботаСАдресами.АвтоподборАдреса(ПараметрыПоиска);
Если РезультатПоиска.Количество() > 0 Тогда
НайденныйАдрес = РезультатПоиска[0];
// Здесь мы получаем структуру с идентификаторами ФИАС
Сообщить("Найден адрес: " + НайденныйАдрес.Представление);
КонецЕсли;
Преимущество этого метода в том, что он учитывает актуальные классификаторы, загруженные в вашу базу. Однако он требует, чтобы данные ФИАС/ГАР были предварительно загружены для соответствующих регионов.
Когда в строке адреса допущены ошибки («Архангильская» вместо «Архангельская»), стандартный поиск по строке может не сработать. В 1С реализован механизм полнотекстового поиска (ПП), который поддерживает нечеткий поиск. Проанализируем, как это можно использовать:
ПолнотекстовыйПоиск.СоздатьСписок() для поиска по строке адреса.Этот подход позволяет находить правильные объекты даже при значительных искажениях в исходном тексте.
Если нам нужно реализовать «offline» разбор без обращения к тяжелым таблицам классификатора на каждом шаге, мы можем применить алгоритм вычисления расстояния Левенштейна. Это число, обозначающее минимальное количество операций (вставка, удаление, замена символа), необходимых для превращения одной строки в другую.
Разберем, как реализовать функцию сравнения строк на языке 1С:
Функция РасстояниеЛевенштейна(Строка1, Строка2) Экспорт
н1 = СтрДлина(Строка1);
н2 = СтрДлина(Строка2);
// Создаем матрицу расстояний
Матрица = Новый ТаблицаЗначений;
Для к = 0 По н2 Цикл
Матрица.Колонки.Добавить("Кол" + к);
КонецЦикла;
Для и = 0 По н1 Цикл
НоваяСтрока = Матрица.Добавить();
НоваяСтрока[0] = и;
КонецЦикла;
Для к = 1 По н2 Цикл
Матрица[0][к] = к;
КонецЦикла;
// Вычисляем стоимость операций
Для и = 1 По н1 Цикл
Для к = 1 По н2 Цикл
Стоимость = ?(Сред(Строка1, и, 1) = Сред(Строка2, к, 1), 0, 1);
Матрица[и][к] = Минимум(
Матрица[и-1][к] + 1, // удаление
Матрица[и][к-1] + 1, // вставка
Матрица[и-1][к-1] + Стоимость // замена
);
КонецЦикла;
КонецЦикла;
Возврат Матрица[н1][н2];
КонецФункции
С помощью этой функции мы можем сравнивать токены из строки (например, «Маяковского») со списком улиц в конкретном населенном пункте и выбирать вариант с минимальным расстоянием.
Адрес часто содержит специфические маркеры: «д.», «корп.», «кв.», «индекс». Для их выделения идеально подходят регулярные выражения. В 1С они доступны через COM-объект VBScript.RegExp.
Выясним, как программно извлечь почтовый индекс из произвольной строки:
// Поиск 6-значного индекса в строке
RegExp = Новый COMОбъект("VBScript.RegExp");
RegExp.Pattern = "\b\d{6}\b";
RegExp.Global = Истина;
Matches = RegExp.Execute(АдреснаяСтрока);
Если Matches.Count > 0 Тогда
Индекс = Matches.Item(0).Value;
Сообщить("Найден индекс: " + Индекс);
КонецЕсли;
Аналогичным образом мы можем построить шаблоны для поиска номеров домов, которые обычно располагаются в конце строки или после слова «дом»/«д».
Проанализируем наиболее эффективный алгоритм самостоятельного разбора строки без использования внешних API:
Важный момент: Если система находит несколько населенных пунктов с одинаковым названием (например, деревня «Николаевка»), обязательно учитывайте подчиненность району, иначе разбор будет некорректным.
Мы рассмотрели различные подходы к разбору адреса. Использование БСП является наиболее предпочтительным в типовых решениях, так как оно минимизирует написание собственного кода и использует проверенные государственные справочники. Однако для сложных случаев с плохим качеством входных данных комбинация регулярных выражений и нечеткого поиска позволит добиться гораздо более высокой точности автоматической обработки.