При обработке текстовой информации в 1С часто возникает задача разбора артикулов, номеров документов или иных кодов, имеющих составную структуру. Например, если нам поступают строки вида «99-2017» и «100-2017», требуется быстро определить, сколько именно символов или цифр находится до символа-разделителя (дефиса «-»), чтобы применить соответствующую бизнес-логику.
Рассмотрим подробно несколько проверенных способов решения этой задачи на встроенном языке 1С, а также проанализируем краевые случаи и возможные ошибки при работе со строками.
Самый базовый и классический подход заключается в поиске позиции разделителя в строке и последующем вычислении длины подстроки, находящейся слева от него. Для этого в платформе 1С предусмотрена функция СтрНайти (или устаревшая функция Найти).
Разберем пример кода, который решает эту задачу:
ИсходнаяСтрока = СокрЛП(СтрокаЗначение);
Позиция = СтрНайти(ИсходнаяСтрока, "-");
Если Позиция > 0 Тогда
ДлинаПрефикса = Позиция - 1;
Если ДлинаПрефикса = 2 Тогда
// Логика, если перед дефисом 2 символа
ИначеЕсли ДлинаПрефикса = 3 Тогда
// Логика, если перед дефисом 3 символа
КонецЕсли;
КонецЕсли;
Проанализируем этот код:
СокрЛП очищает строку от нежелательных краевых пробелов слева и справа.СтрНайти возвращает порядковый номер первого вхождения символа «-». Если символ дефиса находится на 3-й позиции (как в «99-2017»), то вычитание единицы Позиция - 1 даст ровно 2 — количество символов перед разделителем.Если Позиция > 0 обязательна: если разделитель в строке отсутствует, функция вернет 0. Без этой проверки попытка обратиться к подстроке вызовет ошибку выполнения.Начиная с версии платформы 8.3.6, в 1С доступна встроенная функция СтрРазделить. Она позволяет мгновенно расщепить исходный текст на массив подстрок по заданному разделителю, избавив нас от необходимости вручную вычислять позиции символов.
Рассмотрим, как применить СтрРазделить в нашей задаче:
ИсходнаяСтрока = СокрЛП(СтрокаЗначение);
МассивЧастей = СтрРазделить(ИсходнаяСтрока, "-");
Если МассивЧастей.Количество() > 1 Тогда
ДлинаПрефикса = СтрДлина(МассивЧастей[0]);
Если ДлинаПрефикса = 2 Тогда
// Действия для 2 символов
ИначеЕсли ДлинаПрефикса = 3 Тогда
// Действия для 3 символов
КонецЕсли;
КонецЕсли;
Посмотрим на преимущества данного метода: код получается более читаемым и лаконичным. Первый элемент массива МассивЧастей[0] будет содержать подстроку до дефиса, и функция СтрДлина вернет ее точную длину.
Если требуется не просто узнать длину подстроки, но и убедиться, что до дефиса находятся именно цифры, а не произвольные буквы или знаки, выгодно использовать регулярные выражения. На платформе под управлением Windows это реализуется через COM-объект VBScript.RegExp.
Рассмотрим пример кода:
ИсходнаяСтрока = СокрЛП(СтрокаЗначение);
РегЭксп = Новый COMОбъект("VBScript.RegExp");
РегЭксп.Pattern = "^\d+(?=-)"; // Ищет только цифры от начала строки до дефиса
Совпадения = РегЭксп.Execute(ИсходнаяСтрока);
Если Совпадения.Количество > 0 Тогда
КоличествоЦифр = Совпадения.Item(0).Length;
// КоличествоЦифр содержит точное число цифр перед дефисом
КонецЕсли;
Специальный шаблон ^\d+(?=-) гарантирует, что проверяемая подстрока начинается строго с цифр и заканчивается непосредственно перед символом дефиса.
При работе со строковыми функциями в 1С важно учитывать нюансы входных данных, которые могут привести к сбоям или неверным расчетам:
СтрНайти вернет 0. Вычисление Позиция - 1 даст -1. Передача отрицательного числа в функцию Лев(Строка, -1) приведет к критической ошибке платформы «Недопустимое значение параметра».СокрЛП удаляет только обычные пробелы. Если в тексте присутствуют неразрывные пробелы (символ с кодом 160 или Символы.НПП), они останутся в строке и исказят расчет длины. Для их удаления следует предварительно применить функцию СтрЗаменить(Строка, Символы.НПП, "").СтрНайти(Строка, "-") их не найдет.COMОбъект("VBScript.RegExp") работает исключительно на серверах и клиентах под управлением Windows. При выполнении кода на сервере 1С под Linux вызов COM-объекта завершится ошибкой.