Как выделить название города из строки адреса в 1С

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

В процессе разработки часто возникает задача парсинга (разбора) текстовых строк, которые имеют определенную, но не всегда удобную структуру. Рассмотрим классический пример: из полной строки адреса, оформленной по строгому шаблону, необходимо программно извлечь название города. Предположим, адрес выглядит так: "РФ, 119334, (Москва, ул. Вавилова, дом № 5...)". Наша цель — получить слово "Москва", которое всегда находится между первой открывающей скобкой ( и первой последующей запятой ,.

Разберем несколько подходов к решению этой задачи: от классических методов работы со строками до современных регулярных выражений, а также затронем профессиональные инструменты разбора адресов.

Способ 1: Классические функции работы со строками

Этот метод является универсальным и будет работать на любой версии платформы 1С. Мы будем использовать функции СтрНайти(), Сред() и Лев(). Проанализируем алгоритм: сначала найдем позицию открывающей скобки, затем определим, где стоит следующая за ней запятая, и «вырежем» нужный фрагмент.

Рассмотрим пошаговую реализацию:


Функция ИзвлечьГородИзСтроки(Знач НаименованиеОфиса) Экспорт 

    Результат = "";
    
    // 1. Находим позицию открывающей скобки
    ПозицияНачала = СтрНайти(НаименованиеОфиса, "(");
    
    Если ПозицияНачала > 0 Тогда
        
        // Отрезаем всё, что идет после скобки, чтобы искать запятую только в нужной части
        СтрокаПослеСкобки = Сред(НаименованиеОфиса, ПозицияНачала + 1);
        
        // 2. Находим позицию первой запятой в остатке строки
        ПозицияЗапятой = СтрНайти(СтрокаПослеСкобки, ",");
        
        Если ПозицияЗапятой > 0 Тогда
            // 3. Извлекаем текст от начала остатка до запятой
            Результат = СокрЛП(Лев(СтрокаПослеСкобки, ПозицияЗапятой - 1));
        КонецЕсли;
        
    КонецЕсли;
    
    Возврат Результат;

КонецФункции

Преимущество этого метода: высокая скорость работы и надежность. В отличие от сложных алгоритмов, простые строковые функции потребляют минимум ресурсов и предсказуемы в поведении. Это лучший выбор, если структура строки гарантированно неизменна.

Способ 2: Использование регулярных выражений (Платформа 8.3.23+)

В современных версиях платформы 1С (начиная с 8.3.23) появился встроенный механизм работы с регулярными выражениями. Это позволяет решить задачу буквально одной строкой кода. Для извлечения текста между скобкой и запятой воспользуемся функцией СтрНайтиПоРегулярномуВыражению().

Проанализируем подходящий шаблон (регулярное выражение): "(?<=\().*?(?=,)". Здесь используются так называемые «просмотры»:

Пример программного кода:


НаименованиеОфиса = "РФ, 119334, (Москва, ул. Вавилова, дом № 5)";
РезультатПоиска = СтрНайтиПоРегулярномуВыражению(НаименованиеОфиса, "(?<=\().*?(?=,)");

Если РезультатПоиска <> Неопределено Тогда
    Город = РезультатПоиска.Значение;
    Сообщить(Город); // Выведет: Москва
КонецЕсли;

Существует и более строгий вариант регулярного выражения: "(?<=\()[^,]*(?=,)". Вместо точки (любого символа) мы указываем [^,]*, что означает «любые символы, кроме запятой». Это работает быстрее и исключает ошибки, если внутри скобок по какой-то причине отсутствует запятая.

Способ 3: Метод разделения строки (СтрРазделить)

Если формат строки подразумевает, что город — это всегда определенный элемент в списке, разделенном запятыми, можно воспользоваться функцией СтрРазделить(). Посмотрим на логику: если мы разделим строку по запятым, то элемент, содержащий город, будет включать в себя открывающую скобку.


МассивПодстрок = СтрРазделить(НаименованиеОфиса, ",");
// Предположим, что фрагмент с городом всегда третий по счету (индекс 2)
Если МассивПодстрок.Количество() > 2 Тогда
    ГородСЛишнимСимволом = МассивПодстрок[2]; // Получим " (Москва"
    Город = СокрЛП(СтрЗаменить(ГородСЛишнимСимволом, "(", ""));
КонецЕсли;

Важное замечание: этот метод менее надежен, так как он сильно зависит от количества запятых перед скобкой. Если формат адреса изменится (например, добавят индекс или регион через запятую), индекс в массиве станет неверным.

Профессиональный подход: Использование БСП и классификаторов

Выясним причину, по которой ручной разбор строки может быть опасен в реальных учетных системах. Адреса часто вводятся пользователями с ошибками: лишние пробелы, отсутствие скобок, использование «г.» или «гор.» перед названием. В таких случаях регулярные выражения могут «сломаться».

Если ваша конфигурация построена на базе БСП (Библиотеки стандартных подсистем), рекомендуется использовать программный интерфейс модуля УправлениеКонтактнойИнформацией. Рассмотрим преимущества:

  1. Нормализация: БСП умеет преобразовывать произвольную строку в структуру адреса, опираясь на внутренние алгоритмы сопоставления.
  2. Работа с ГАР/ФИАС: Вместо поиска текста "Москва", система может найти уникальный идентификатор города в государственном адресном реестре.
  3. Устойчивость: Профессиональные парсеры учитывают сокращения («г.», «с.», «пгт») и могут корректно выделить город, даже если структура скобок нарушена.

Для интеграции с внешними системами также часто используют сервис DaData. Через HTTPЗапрос в 1С можно отправить «грязную» строку адреса и получить структурированный JSON, где город будет выделен в отдельное поле с официальным кодом ФИАС. Это исключает проблемы с городами-двойниками (например, Ростов и Ростов-на-Дону).

Риски и производительность

Проанализируем ситуацию с точки зрения нагрузки на сервер. Использование регулярных выражений к очень длинным строкам может вызвать проблему «катастрофического отката» (ReDoS), если шаблон составлен некорректно. Если вы обрабатываете тысячи адресов в цикле, простые функции СтрНайти и Сред всегда будут работать в несколько раз быстрее регулярных выражений.

Подведем итог:

← На главную