В практике программирования в среде «1С:Предприятие» довольно часто возникает задача предварительной обработки текстовых данных. Классический пример — получение чистых слов из строки, содержащей различный «мусор»: знаки препинания, цифры, служебные символы или разделители. Например, если на входе мы имеем строку вида "Надо$Разбить2На/Массив)", на выходе нам нужно получить чистый массив слов: "Надо", "Разбить", "На", "Массив".
В этой статье мы подробно разберем, как решить эту задачу несколькими способами. Мы проанализируем как классический подход с использованием COM-объекта регулярных выражений, так и современные кроссплатформенные механизмы, появившиеся в платформе 1С начиная с версии 8.3.23, а также альтернативные варианты с использованием Библиотеки Стандартных Подсистем (БСП).
Рассмотрим исходную ситуацию. Нам необходимо очистить строку от любых символов, кроме букв (причем буквы могут быть как кириллическими, так и латинскими), и сформировать из оставшихся слов массив. Сложность заключается в том, что перечислять все возможные спецсимволы вручную через стандартную функцию СтрРазделить — крайне неэффективный путь, так как спецсимволов в кодировке Unicode может быть огромное количество.
Поэтому наиболее правильным подходом здесь является использование регулярных выражений (RegExp). Мы можем пойти двумя путями:
Ниже мы подробно разберем реализацию каждого из этих подходов.
Если ваша информационная база работает на версии платформы ниже 8.3.23 и исключительно под управлением операционной системы Windows, то стандартным решением является использование COM-объекта VBScript.RegExp.
Проанализируем пример кода, который решает нашу задачу через выделение всех последовательностей букв латиницы и кириллицы:
Функция РазложитьСтрокуВМассив(Строка) Экспорт
RegExp = Новый COMОбъект("VBScript.RegExp");
RegExp.Global = Истина;
RegExp.IgnoreCase = Истина;
// Шаблон находит любые последовательности букв русского и английского алфавитов
RegExp.Pattern = "[a-zа-яё]+";
Matches = RegExp.Execute(Строка);
Массив = Новый Массив;
Для Сч = 0 По Matches.Count - 1 Цикл
Массив.Добавить(Matches.Item(Сч).Value);
КонецЦикла;
RegExp = Неопределено;
Возврат Массив;
КонецФункции
Как работает этот код:
VBScript.RegExp.Global = Истина, чтобы поиск производился по всей строке, а не прекращался после первого найденного совпадения.IgnoreCase = Истина позволяет нам не дублировать заглавные буквы в шаблоне поиска (шаблон [a-zа-яё] автоматически охватывает и заглавные буквы).[a-zа-яё]+ означает: найти одну или более букв латиницы или кириллицы, идущих подряд. Любой другой символ (цифра, знак препинания, спецсимвол) будет проигнорирован и послужит естественной границей слова.Execute выполняет поиск и возвращает коллекцию совпадений, которые мы в цикле обходим и добавляем в результирующий массив.Важное ограничение: данный метод жестко привязан к ОС Windows. Если ваш сервер 1С работает под управлением Linux или база запущена в macOS / мобильном клиенте, этот код работать не будет и вызовет критическую ошибку.
Начиная с версии платформы 8.3.23, в 1С реализована встроенная поддержка регулярных выражений на уровне ядра платформы. Механизм базируется на международном стандарте ICU (International Components for Unicode), что дает колоссальные преимущества:
Рассмотрим два элегантных способа решения нашей задачи с использованием новых встроенных функций.
В данном способе мы заменим любую последовательность «не-букв» на одиночные пробелы с помощью функции СтрЗаменитьПоРегулярномуВыражению. Для этого мы применим мощный Unicode-класс \P{L}, который обозначает любой символ, не являющийся буквой в любом алфавите мира.
Посмотрим на пример практической реализации:
// Определяем исходную строку со спецсимволами
ИсходнаяСтрока = "Надо$Разбить2На/Массив)";
// Шаблон "\P{L}+" находит любую последовательность символов, не являющихся буквами
// (сюда входят цифры, знаки препинания, скобки, спецсимволы)
СтрокаБезСпецсимволов = СтрЗаменитьПоРегулярномуВыражению(ИсходнаяСтрока, "\P{L}+", " ");
// Разделяем очищенную строку по пробелам, игнорируя пустые подстроки
МассивСлов = СтрРазделить(СтрокаБезСпецсимволов, " ", Ложь);
// В результате МассивСлов будет содержать: "Надо", "Разбить", "На", "Массив"
Этот способ невероятно лаконичен и занимает всего пару строк кода. Он автоматически обрабатывает буквы любых алфавитов (включая кириллицу, латиницу, диакритические знаки и т.д.), избавляя разработчика от необходимости вручную прописывать диапазоны символов.
Если мы хотим сразу извлечь слова из строки без промежуточной замены символов, мы можем использовать функцию СтрНайтиВсеПоРегулярномуВыражению. В качестве шаблона мы укажем \p{L}+, что означает «одна или более букв любого алфавита»:
ИсходнаяСтрока = "Надо$Разбить2На/Массив)";
// Ищем все вхождения последовательностей букв
МассивРезультатов = СтрНайтиВсеПоРегулярномуВыражению(ИсходнаяСтрока, "\p{L}+");
МассивСлов = Новый Массив;
Для Каждого Результат Из МассивРезультатов Цикл
// Результат имеет тип "РезультатПоискаПоРегулярномуВыражению"
Слово = Сред(ИсходнаяСтрока, Результат.НачальнаяПозиция, Результат.Длина);
МассивСлов.Добавить(Слово);
КонецЦикла;
Данный способ также является полностью кроссплатформенным и надежным, предоставляя разработчику полный контроль над процессом разбора строки.
Если вы работаете на платформе ниже 8.3.23, но в вашей конфигурации интегрирована Библиотека Стандартных Подсистем (БСП), вы можете избежать написания собственных сложных парсеров. В БСП предусмотрены готовые функции общего назначения для работы со строками.
Например, в общем модуле СтроковыеФункцииКлиентСервер существует функция РазложитьСтрокуВМассивПодстрок. Мы можем передать в неё строку со спецсимволами, предварительно подготовив строку-разделитель из часто встречающихся знаков:
СписокРазделителей = ",./;$()[]{}*?%№+-1234567890"; // Добавляем известные спецсимволы и цифры
МассивСлов = СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок(ИсходнаяСтрока, СписокРазделителей);
Конечно, этот метод уступает регулярным выражениям в гибкости, так как вам все равно придется самостоятельно формировать перечень нежелательных символов в переменной СписокРазделителей. Тем не менее, для простых прикладных задач в рамках БСП это готовое и надежное решение.
Подводя итог, выделим ключевые рекомендации по работе со спецсимволами в 1С:
СтрЗаменитьПоРегулярномуВыражению или СтрНайтиВсеПоРегулярномуВыражению с классами символов \P{L} или \p{L}. Это наиболее быстрый, современный и кроссплатформенный вариант.VBScript.RegExp с шаблоном [a-zа-яё]+.