В практике программирования на платформе 1С часто возникает задача разделения слипшихся строк, где артикул или код товара (на латинице или цифрах) переходит в наименование (на кириллице) без явного разделителя. Например, из строки 16113Темно-синий нам необходимо получить две отдельные части: 16113 и Темно-синий. Рассмотрим подробно несколько эффективных способов решения этой задачи, проанализируем их плюсы и минусы, а также разберем типичные ошибки.
Этот метод считается классическим и наиболее понятным для начинающих разработчиков. Суть заключается в том, что мы создаем строку, содержащую все буквы русского алфавита, и в цикле проверяем каждый символ исходного текста на вхождение в этот эталон. Проанализируем реализацию этого алгоритма:
Функция РазделитьСтрокуПоКириллице(Знач Текст)
СимволыКириллицы = "абвгдеёжзийклмнопрстуфхцчшщъыьэюя";
ТекстНРег = НРег(Текст); // Переводим в нижний регистр для корректного сравнения
ПозицияРазделения = 0;
Для Сч = 1 По СтрДлина(Текст) Цикл
Символ = Сред(ТекстНРег, Сч, 1);
Если Найти(СимволыКириллицы, Символ) > 0 Тогда
ПозицияРазделения = Сч;
Прервать; // Нашли первую русскую букву, выходим из цикла
КонецЕсли;
КонецЦикла;
Результат = Новый Массив;
Если ПозицияРазделения > 0 Тогда
Результат.Добавить(Лев(Текст, ПозицияРазделения - 1));
Результат.Добавить(Сред(Текст, ПозицияРазделения));
Иначе
Результат.Добавить(Текст);
Результат.Добавить("");
КонецЕсли;
Возврат Результат;
КонецФункции
В данном примере мы используем функцию НРег(), чтобы привести строку к нижнему регистру. Это избавляет нас от необходимости прописывать в переменной СимволыКириллицы еще и заглавные буквы. Обратите внимание на использование функции Прервать: как только мы находим первый символ, похожий на русскую букву, цикл останавливается, сохраняя индекс этого символа.
Рассмотрим более производительный вариант, который не требует создания вспомогательных строк-эталонов. Мы будем использовать функцию КодСимвола(). Коды букв кириллицы в кодировке Unicode находятся в определенных числовых диапазонах. Основной массив русских букв (А-я) занимает диапазон от 1040 до 1103.
Важный нюанс: Буква "Ё" (код 1025) и "ё" (код 1105) стоят в таблице символов отдельно, поэтому их нужно проверять дополнительным условием. Выясним, как написать такой код:
Функция НайтиПервуюКириллицуПоКоду(Текст)
Для Сч = 1 По СтрДлина(Текст) Цикл
Код = КодСимвола(Текст, Сч);
// Проверяем диапазон А-я, а также коды букв Ё и ё
Если (Код >= 1040 И Код <= 1103) Или Код = 1025 Или Код = 1105 Тогда
Возврат Сч;
КонецЕсли;
КонецЦикла;
Возврат 0;
КонецФункции
Этот метод работает быстрее, так как сравнение чисел — это элементарная операция для процессора, в отличие от поиска подстроки функцией Найти(). Мы рекомендуем использовать именно этот подход при обработке больших массивов данных.
Если ваша задача подразумевает более сложные условия (например, нужно игнорировать знаки препинания или учитывать специфические символы), лучше всего воспользоваться объектом VBScript.RegExp. Это мощный инструмент поиска по шаблону. Разберем по шагам, как его внедрить в 1С:
Функция РазделитьСтрокуRegExp(Текст)
RegExp = Новый COMОбъект("VBScript.RegExp");
RegExp.IgnoreCase = Истина;
RegExp.Global = Ложь; // Нам нужно только первое вхождение
RegExp.Pattern = "[а-яё]"; // Шаблон ищет любую русскую букву
Matches = RegExp.Execute(Текст);
Результат = Новый Массив;
Если Matches.Count > 0 Тогда
ПервоеСовпадение = Matches.Item(0);
Позиция = ПервоеСовпадение.FirstIndex + 1; // Индексация в COM начинается с 0
Результат.Добавить(Лев(Текст, Позиция - 1));
Результат.Добавить(Сред(Текст, Позиция));
Иначе
Результат.Добавить(Текст);
Результат.Добавить("");
КонецЕсли;
Возврат Результат;
КонецФункции
Использование регулярных выражений позволяет сделать код очень лаконичным. Шаблон [а-яё] автоматически находит любую кириллическую букву независимо от регистра, если установлено свойство IgnoreCase = Истина.
Проанализируем ситуацию, описанную в одном из сообщений форума. При обработке строки B.771.KISAярко-красный автор заметил, что буква "А" в конце артикула исчезла или переместилась. Почему это происходит?
СокрЛП() для обеих подстрок, чтобы очистить их от невидимых символов в начале и конце.Сред(Текст, 0).Для простых задач внутри корпоративной базы 1С оптимальным выбором будет Способ №2 (проверка кодов символов). Он надежен, не зависит от установленных в системе COM-объектов и обладает высокой скоростью работы. Если же вам нужно обрабатывать сложные строки с непостоянной структурой, потратьте время на изучение регулярных выражений — этот навык неоднократно пригодится вам в будущем при парсинге данных или загрузке прайс-листов.
Посмотрим на финальный пример того, как можно красиво оформить результат разделения для пользователя:
ЧастиСтроки = РазделитьСтрокуПоКириллице("B.771.KISAярко-красный");
Сообщить("Артикул: " + СокрЛП(ЧастиСтроки[0]));
Сообщить("Цвет: " + СокрЛП(ЧастиСтроки[1]));
Таким образом, мы не только разделяем данные, но и гарантируем отсутствие лишних пробелов, которые могут помешать дальнейшему поиску товаров в базе данных.