В процессе разработки в 1С часто возникает задача разобрать текстовую строку, полученную из внешнего источника, логов или введённую пользователем вручную. Типичный пример такой строки: "мол: Иванов Иван Иванович ; должность: строитель; пол: мужской;". Основная сложность заключается в том, что порядок параметров может меняться, а некоторые из них могут вовсе отсутствовать.
В этой статье мы подробно разберем несколько подходов к решению этой задачи: от самых простых методов до продвинутых способов с использованием коллекций и регулярных выражений.
Этот метод является наиболее лаконичным, если мы заранее знаем, что формат строки строго соблюдается. Функция СтрРазделить в современных версиях платформы 8.3 позволяет указывать сразу несколько символов-разделителей в одной строке.
Рассмотрим пример, где мы разбиваем строку одновременно по двоеточию и точке с запятой:
ИсходнаяСтрока = "мол: Иванов Иван Иванович ; должность: строитель; пол: мужской;";
// Указываем вторым параметром строку со всеми возможными разделителями
МассивПодстрок = СтрРазделить(ИсходнаяСтрока, ";:");
Для Индекс = 0 По МассивПодстрок.Количество() - 1 Цикл
// Каждое нечетное значение (индекс 1, 3, 5...) будет содержать данные
Если Индекс % 2 <> 0 Тогда
Сообщить("Найденное значение: " + СокрЛП(МассивПодстрок[Индекс]));
КонецЕсли;
КонецЦикла;
Важный нюанс: при таком подходе мы сильно зависим от порядка следования элементов. Если какой-то ключ (например, "должность") будет пропущен, индексы могут сместиться. Поэтому данный способ хорош только для простых и стабильных структур.
Чтобы сделать код более устойчивым к изменениям, проанализируем ситуацию, когда мы сначала разбиваем строку на пары "Ключ: Значение", а затем каждую пару разбираем отдельно. Это позволяет нам не зависеть от общего количества элементов в строке.
Разберем по шагам этот алгоритм:
ИсходнаяСтрока = "мол: Иванов Иван Иванович ; должность: строитель; пол: мужской;";
// Шаг 1: Разделяем строку на блоки по точке с запятой
МассивПар = СтрРазделить(ИсходнаяСтрока, ";", Ложь);
Для Каждого ТекущаяПара Из МассивПар Цикл
// Шаг 2: Каждую пару разделяем по двоеточию
ЧастиПары = СтрРазделить(ТекущаяПара, ":");
Если ЧастиПары.Количество() = 2 Тогда
Ключ = СокрЛП(ЧастиПары[0]);
Значение = СокрЛП(ЧастиПары[1]);
Сообщить("Параметр: " + Ключ + " = " + Значение);
КонецЕсли;
КонецЦикла;
Обратите внимание на использование третьего параметра Ложь в функции СтрРазделить. Это гарантирует, что если в конце строки стоит точка с запятой, программа не создаст лишний пустой элемент в массиве, который мог бы привести к ошибке при дальнейшем разборе.
Если нам нужно не просто вывести данные на экран, а использовать их дальше в коде, лучше всего сохранять их в специализированную коллекцию. Рассмотрим использование объекта Соответствие.
ИсходнаяСтрока = "мол: Иванов Иван Иванович ; должность: строитель; пол: мужской;";
Результат = Новый Соответствие;
МассивПар = СтрРазделить(ИсходнаяСтрока, ";", Ложь);
Для Каждого Стр Из МассивПар Цикл
МассивПодстрок = СтрРазделить(Стр, ":");
Если МассивПодстрок.Количество() = 2 Тогда
Результат.Вставить(СокрЛП(МассивПодстрок[0]), СокрЛП(МассивПодстрок[1]));
КонецЕсли;
КонецЦикла;
// Теперь мы можем легко получить значение по ключу, независимо от его позиции
Должность = Результат.Получить("должность");
Проанализируем преимущества этого метода: мы можем проверить наличие любого параметра с помощью метода Получить(). Если параметр не найден, функция вернет Неопределено, что позволит избежать аварийного завершения программы.
Если ключи в строке гарантированно не содержат пробелов и спецсимволов, можно использовать объект Структура. Это позволит обращаться к свойствам через точку: Данные.мол.
Выясним причину, по которой стандартные строковые функции могут не подойти. Если в значениях самих по себе могут встречаться двоеточия или точки с запятой, СтрРазделить отработает некорректно. В таких случаях на помощь приходят регулярные выражения.
Хотя в 1С нет встроенного объекта для RegExp, мы можем воспользоваться COM-объектом:
RegExp = Новый COMОбъект("VBScript.RegExp");
RegExp.IgnoreCase = Истина;
RegExp.Global = Истина;
RegExp.MultiLine = Истина;
// Шаблон ищет текст между ключом и разделителем
RegExp.Pattern = "должность:\s*([^;]+)";
Matches = RegExp.Execute(ИсходнаяСтрока);
Если Matches.Count > 0 Тогда
ЗначениеДолжности = СокрЛП(Matches.Item(0).SubMatches.Item(0));
Сообщить("Найдено регулярным выражением: " + ЗначениеДолжности);
КонецЕсли;
Посмотрим на ситуацию шире. Часто данные приходят из веб-форм или Excel, где могут содержаться невидимые символы. Самый коварный из них — неразрывный пробел (код 160). Стандартная функция СокрЛП его "не видит".
Рекомендуем перед разбором выполнять предварительную очистку:
// Заменяем неразрывные пробелы на обычные
ЧистаяСтрока = СтрЗаменить(ИсходнаяСтрока, Символы.НПП, " ");
// Убираем возможные переносы строк, если они есть внутри данных
ЧистаяСтрока = СтрЗаменить(ЧистаяСтрока, Символы.ПС, "");
ЧистаяСтрока = СтрЗаменить(ЧистаяСтрока, Символы.ВК, "");
Если ваша строка напоминает формат JSON, иногда проще превратить её в валидный JSON-объект. Это актуально, если пар предстоит разбирать очень много и структура вложенная.
Алгоритм действий следующий:
":" (с кавычками).ПрочитатьJSON.Это превратит строку в полноценный объект 1С (Структуру или Соответствие) за одну операцию штатным механизмом платформы.
Мы рассмотрели различные подходы к разбору строк. Для простых задач идеально подходит двойной СтрРазделить. Если же данные приходят из ненадежных источников, лучше использовать комбинацию из предварительной очистки (удаление Символы.НПП) и сохранения результатов в Структуру или Соответствие для удобного доступа к параметрам по именам.