В процессе разработки часто возникает задача парсинга (разбора) текстовых строк, которые имеют определенную, но не всегда удобную структуру. Рассмотрим классический пример: из полной строки адреса, оформленной по строгому шаблону, необходимо программно извлечь название города. Предположим, адрес выглядит так: "РФ, 119334, (Москва, ул. Вавилова, дом № 5...)". Наша цель — получить слово "Москва", которое всегда находится между первой открывающей скобкой ( и первой последующей запятой ,.
Разберем несколько подходов к решению этой задачи: от классических методов работы со строками до современных регулярных выражений, а также затронем профессиональные инструменты разбора адресов.
Этот метод является универсальным и будет работать на любой версии платформы 1С. Мы будем использовать функции СтрНайти(), Сред() и Лев(). Проанализируем алгоритм: сначала найдем позицию открывающей скобки, затем определим, где стоит следующая за ней запятая, и «вырежем» нужный фрагмент.
Рассмотрим пошаговую реализацию:
Функция ИзвлечьГородИзСтроки(Знач НаименованиеОфиса) Экспорт
Результат = "";
// 1. Находим позицию открывающей скобки
ПозицияНачала = СтрНайти(НаименованиеОфиса, "(");
Если ПозицияНачала > 0 Тогда
// Отрезаем всё, что идет после скобки, чтобы искать запятую только в нужной части
СтрокаПослеСкобки = Сред(НаименованиеОфиса, ПозицияНачала + 1);
// 2. Находим позицию первой запятой в остатке строки
ПозицияЗапятой = СтрНайти(СтрокаПослеСкобки, ",");
Если ПозицияЗапятой > 0 Тогда
// 3. Извлекаем текст от начала остатка до запятой
Результат = СокрЛП(Лев(СтрокаПослеСкобки, ПозицияЗапятой - 1));
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Преимущество этого метода: высокая скорость работы и надежность. В отличие от сложных алгоритмов, простые строковые функции потребляют минимум ресурсов и предсказуемы в поведении. Это лучший выбор, если структура строки гарантированно неизменна.
В современных версиях платформы 1С (начиная с 8.3.23) появился встроенный механизм работы с регулярными выражениями. Это позволяет решить задачу буквально одной строкой кода. Для извлечения текста между скобкой и запятой воспользуемся функцией СтрНайтиПоРегулярномуВыражению().
Проанализируем подходящий шаблон (регулярное выражение): "(?<=\().*?(?=,)".
Здесь используются так называемые «просмотры»:
(?<=\() — положительный просмотр назад (ищем место после скобки, но не включаем её в результат)..*? — ленивый поиск любых символов (берем минимально возможный набор символов до первого ограничителя).(?=,) — положительный просмотр вперед (ищем место перед запятой, но не включаем её в результат).Пример программного кода:
НаименованиеОфиса = "РФ, 119334, (Москва, ул. Вавилова, дом № 5)";
РезультатПоиска = СтрНайтиПоРегулярномуВыражению(НаименованиеОфиса, "(?<=\().*?(?=,)");
Если РезультатПоиска <> Неопределено Тогда
Город = РезультатПоиска.Значение;
Сообщить(Город); // Выведет: Москва
КонецЕсли;
Существует и более строгий вариант регулярного выражения: "(?<=\()[^,]*(?=,)". Вместо точки (любого символа) мы указываем [^,]*, что означает «любые символы, кроме запятой». Это работает быстрее и исключает ошибки, если внутри скобок по какой-то причине отсутствует запятая.
Если формат строки подразумевает, что город — это всегда определенный элемент в списке, разделенном запятыми, можно воспользоваться функцией СтрРазделить(). Посмотрим на логику: если мы разделим строку по запятым, то элемент, содержащий город, будет включать в себя открывающую скобку.
МассивПодстрок = СтрРазделить(НаименованиеОфиса, ",");
// Предположим, что фрагмент с городом всегда третий по счету (индекс 2)
Если МассивПодстрок.Количество() > 2 Тогда
ГородСЛишнимСимволом = МассивПодстрок[2]; // Получим " (Москва"
Город = СокрЛП(СтрЗаменить(ГородСЛишнимСимволом, "(", ""));
КонецЕсли;
Важное замечание: этот метод менее надежен, так как он сильно зависит от количества запятых перед скобкой. Если формат адреса изменится (например, добавят индекс или регион через запятую), индекс в массиве станет неверным.
Выясним причину, по которой ручной разбор строки может быть опасен в реальных учетных системах. Адреса часто вводятся пользователями с ошибками: лишние пробелы, отсутствие скобок, использование «г.» или «гор.» перед названием. В таких случаях регулярные выражения могут «сломаться».
Если ваша конфигурация построена на базе БСП (Библиотеки стандартных подсистем), рекомендуется использовать программный интерфейс модуля УправлениеКонтактнойИнформацией. Рассмотрим преимущества:
"Москва", система может найти уникальный идентификатор города в государственном адресном реестре.Для интеграции с внешними системами также часто используют сервис DaData. Через HTTPЗапрос в 1С можно отправить «грязную» строку адреса и получить структурированный JSON, где город будет выделен в отдельное поле с официальным кодом ФИАС. Это исключает проблемы с городами-двойниками (например, Ростов и Ростов-на-Дону).
Проанализируем ситуацию с точки зрения нагрузки на сервер. Использование регулярных выражений к очень длинным строкам может вызвать проблему «катастрофического отката» (ReDoS), если шаблон составлен некорректно. Если вы обрабатываете тысячи адресов в цикле, простые функции СтрНайти и Сред всегда будут работать в несколько раз быстрее регулярных выражений.
Подведем итог: