один из 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) = "о" Тогда Парам.ТипКвартиры = Перечисления.ТипыКвартир.Офис; иначе Парам.ТипКвартиры = Перечисления.ТипыКвартир.Квартира; КонецЕсли; Парам.Представление = ПолучитьПредставлениеАдреса(Парам); КонецЕсли; КонецЦикла; КонецПроцедуры