один из API сервиса dadata.ru позволяет преобразовать адрес, написанный как попало, в упорядоченную структуру. примерно тоже самое приходилось делать руками — искать в КЛАДР регион, улицу и т.д.

Процедура ОтформатироватьДанные(Парам, Адрес) Экспорт
ТабОтвет = Новый ТаблицаЗначений;
ТабОтвет.Колонки.Добавить("Парам");
ТабОтвет.Колонки.Добавить("Ответ");
Token = "ххх";
Secret = "ххх";
ТекстЗапроса = "{ ""structure"": [ ""ADDRESS"" ], ""data"": [ [ """ + СтрЗаменить(Адрес, Символы.ПС, " ") + """" + " ] ] }";
ИмяВременногоФайла = ПолучитьИмяВременногоФайла();
Текст = Новый ЗаписьТекста(ИмяВременногоФайла, КодировкаТекста.ANSI);
Текст.Закрыть();
Текст = Новый ЗаписьТекста(ИмяВременногоФайла,,, Истина, Символы.ПС);
Текст.Записать(ТекстЗапроса);
Текст.Закрыть();
HTTPЗапрос = Новый HTTPЗапрос();
HTTPЗапрос.АдресРесурса = "/api/v2/clean";
HTTPЗапрос.Заголовки.Вставить("Content-Type", "application/json");
HTTPЗапрос.Заголовки.Вставить("Authorization", "Token " + Token);
HTTPЗапрос.Заголовки.Вставить("X-Secret", Secret);
HTTPЗапрос.Заголовки.Вставить("charset", "UTF-8");
HTTPЗапрос.УстановитьТелоИзДвоичныхДанных(Новый ДвоичныеДанные(ИмяВременногоФайла));
Соединение = Новый HTTPСоединение("dadata.ru",,,,,, Новый ЗащищенноеСоединениеOpenSSL);
ОтветHTTP = Соединение.ОтправитьДляОбработки(HTTPЗапрос);
Ответ = ОтветHTTP.ПолучитьТелоКакСтроку();
УдалитьФайлы(ИмяВременногоФайла);
Если ОтветHTTP.КодСостояния = 200 Тогда
Ответ = Сред(Ответ, 2);
Ответ = Лев(Ответ, СтрДлина(Ответ)-1);
Ответ = СтрЗаменить(Ответ, """data"":", Символы.ПС + """data"":");
Стр1 = СокрЛП(СтрПолучитьСтроку(Ответ, 1));
Стр1 = Лев(Стр1, СтрДлина(Стр1)-1);
Стр1 = Сред(Стр1, Найти(Стр1, "["));
Стр1 = СтрЗаменить(Стр1, "[", "");
Стр1 = СтрЗаменить(Стр1, "]", "");
Стр1 = СтрЗаменить(Стр1, """", "");
Стр1 = СтрЗаменить(Стр1, ",", Символы.ПС);
Стр2 = СокрЛП(СтрПолучитьСтроку(Ответ, 2));
Стр2 = СтрЗаменить(Стр2, """data"": [[", "");
Стр2 = СтрЗаменить(Стр2, "}]]}", "");
Стр2 = СтрЗаменить(Стр2, "},", Символы.ПС);
Для i=1 По СтрЧислоСтрок(Стр1) Цикл
Структ = Новый Структура;
ПредПарам = "";
СтрОтвет = Сред(СокрЛП(СтрПолучитьСтроку(Стр2, i)), 2);
СтрОтвет = СтрЗаменить(СтрОтвет, """: ", Символы.ПС);
Для j=2 По СтрЧислоСтрок(СтрОтвет) Цикл
СтрОтветСтр = СтрПолучитьСтроку(СтрОтвет, j);
Если j=СтрЧислоСтрок(СтрОтвет) Тогда //Найти(СтрОтветСтр, "qc_complete") <> 0
Структ[ПредПарам] = Сред(СтрОтветСтр, 2, СтрДлина(СтрОтветСтр)-5);
Иначе
k = СтрДлина(СтрОтветСтр)-1;
Пока k>0 Цикл
Если Сред(СтрОтветСтр, k, 1) = """" Тогда Прервать;
КонецЕсли;
k=k-1;
КонецЦикла;
Структ.Вставить(Сред(СтрОтветСтр, k+1), "");
Если j>2 Тогда
Пар = Лев(СтрОтветСтр, k-3);
Если Лев(Пар, 1) = """" Тогда Пар = Сред(Пар, 2);
КонецЕсли;
Если Прав(Пар, 1) = """" Тогда Пар = Лев(Пар, СтрДлина(Пар)-1);
КонецЕсли;
Структ[ПредПарам] = Пар;
КонецЕсли;
ПредПарам = Сред(СтрОтветСтр, k+1);
КонецЕсли;
КонецЦикла;
НовСтр = ТабОтвет.Добавить();
НовСтр.Парам = СокрЛП(СтрПолучитьСтроку(Стр1, i));
НовСтр.Ответ = Структ;
КонецЦикла;
Иначе
Сообщить("(-1) Ошибка распознавания данных" + Символы.ПС + Ответ);
КонецЕсли;
Для Каждого Стр Из ТабОтвет Цикл
Если Стр.Парам = "ADDRESS" Тогда
Попытка qc_complete = Число(Стр.Ответ.qc_complete);
Исключение qc_complete = 2;
КонецПопытки;
Если qc_complete = 2 Или qc_complete = 3 Или qc_complete = 4 Или qc_complete = 6 Или qc_complete = 7 Тогда
Сообщить("Адрес не распознан, необходимо ввести вручную ((");
Возврат;
КонецЕсли;
АдресСтрукт = Стр.Ответ;
Парам.Поле1 = ?(АдресСтрукт.postal_code="null", "", АдресСтрукт.postal_code);
Парам.Поле2 = ?(АдресСтрукт.region="null", "", АдресСтрукт.region) + ?(АдресСтрукт.region_type="null", "", " " + АдресСтрукт.region_type);
Парам.Поле3 = ?(АдресСтрукт.area="null", "", АдресСтрукт.area);
Парам.Поле4 = ?(АдресСтрукт.city="null", "", АдресСтрукт.city) + ?(АдресСтрукт.city_type="null", "", " " + АдресСтрукт.city_type);
Парам.Поле5 = ?(АдресСтрукт.settlement="null", "", АдресСтрукт.settlement);
Парам.Поле6 = ?(АдресСтрукт.street="null", "", АдресСтрукт.street) + ?(АдресСтрукт.street_type="null", "", " " + АдресСтрукт.street_type);
Парам.Поле7 = ?(АдресСтрукт.qc_house="10", "", АдресСтрукт.house);
Парам.Поле8 = ?(АдресСтрукт.block="null", "", АдресСтрукт.block);
Парам.Поле9 = ?(АдресСтрукт.flat="null", "", АдресСтрукт.flat);
//Парам.Поле10
//Парам.Комментарий
Парам.ТипДома = ?(Стр.Ответ.qc_house="10", "", АдресСтрукт.house_type);
Парам.ТипКорпуса = ?(Стр.Ответ.block_type="null", "", АдресСтрукт.block_type);
Парам.ТипКвартиры = ?(Стр.Ответ.flat_type="null", "", АдресСтрукт.flat_type);
Если Лев(Парам.ТипДома, 1) = "в" Тогда Парам.ТипДома = Перечисления.ТипыДомов.Владение;
Иначе Парам.ТипДома = Перечисления.ТипыДомов.Дом;
КонецЕсли;
Если Лев(Парам.ТипКорпуса, 1) = "с" Тогда Парам.ТипКорпуса = Перечисления.ТипыКорпусов.Строение;
Иначе Парам.ТипКорпуса = Перечисления.ТипыКорпусов.Корпус;
КонецЕсли;
Если Лев(Парам.ТипКвартиры, 1) = "о" Тогда Парам.ТипКвартиры = Перечисления.ТипыКвартир.Офис;
иначе Парам.ТипКвартиры = Перечисления.ТипыКвартир.Квартира;
КонецЕсли;
Парам.Представление = ПолучитьПредставлениеАдреса(Парам);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
