Как в 1С найти любой спецсимвол в строке и разбить её на массив слов?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

В практике программирования в среде «1С:Предприятие» довольно часто возникает задача предварительной обработки текстовых данных. Классический пример — получение чистых слов из строки, содержащей различный «мусор»: знаки препинания, цифры, служебные символы или разделители. Например, если на входе мы имеем строку вида "Надо$Разбить2На/Массив)", на выходе нам нужно получить чистый массив слов: "Надо", "Разбить", "На", "Массив".

В этой статье мы подробно разберем, как решить эту задачу несколькими способами. Мы проанализируем как классический подход с использованием COM-объекта регулярных выражений, так и современные кроссплатформенные механизмы, появившиеся в платформе 1С начиная с версии 8.3.23, а также альтернативные варианты с использованием Библиотеки Стандартных Подсистем (БСП).

Постановка задачи и анализ вариантов

Рассмотрим исходную ситуацию. Нам необходимо очистить строку от любых символов, кроме букв (причем буквы могут быть как кириллическими, так и латинскими), и сформировать из оставшихся слов массив. Сложность заключается в том, что перечислять все возможные спецсимволы вручную через стандартную функцию СтрРазделить — крайне неэффективный путь, так как спецсимволов в кодировке Unicode может быть огромное количество.

Поэтому наиболее правильным подходом здесь является использование регулярных выражений (RegExp). Мы можем пойти двумя путями:

  1. Определить шаблон для поиска всех допустимых буквенных последовательностей (слов) и извлечь их в массив.
  2. Определить шаблон для поиска спецсимволов (всего, что не является буквой), заменить их на пробелы, а затем разбить полученную строку на массив по пробелам.

Ниже мы подробно разберем реализацию каждого из этих подходов.

Вариант 1. Классический метод через COM-объект 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 = Неопределено;
    Возврат Массив;
    
КонецФункции

Как работает этот код:

  1. Мы создаем объект регулярного выражения VBScript.RegExp.
  2. Устанавливаем свойство Global = Истина, чтобы поиск производился по всей строке, а не прекращался после первого найденного совпадения.
  3. Свойство IgnoreCase = Истина позволяет нам не дублировать заглавные буквы в шаблоне поиска (шаблон [a-zа-яё] автоматически охватывает и заглавные буквы).
  4. Шаблон [a-zа-яё]+ означает: найти одну или более букв латиницы или кириллицы, идущих подряд. Любой другой символ (цифра, знак препинания, спецсимвол) будет проигнорирован и послужит естественной границей слова.
  5. Метод Execute выполняет поиск и возвращает коллекцию совпадений, которые мы в цикле обходим и добавляем в результирующий массив.

Важное ограничение: данный метод жестко привязан к ОС Windows. Если ваш сервер 1С работает под управлением Linux или база запущена в macOS / мобильном клиенте, этот код работать не будет и вызовет критическую ошибку.

Вариант 2. Современный кроссплатформенный подход (Платформа 8.3.23 и выше)

Начиная с версии платформы 8.3.23, в 1С реализована встроенная поддержка регулярных выражений на уровне ядра платформы. Механизм базируется на международном стандарте ICU (International Components for Unicode), что дает колоссальные преимущества:

Рассмотрим два элегантных способа решения нашей задачи с использованием новых встроенных функций.

Способ А. Замена спецсимволов на пробелы с последующим разделением

В данном способе мы заменим любую последовательность «не-букв» на одиночные пробелы с помощью функции СтрЗаменитьПоРегулярномуВыражению. Для этого мы применим мощный Unicode-класс \P{L}, который обозначает любой символ, не являющийся буквой в любом алфавите мира.

Посмотрим на пример практической реализации:


// Определяем исходную строку со спецсимволами
ИсходнаяСтрока = "Надо$Разбить2На/Массив)";

// Шаблон "\P{L}+" находит любую последовательность символов, не являющихся буквами
// (сюда входят цифры, знаки препинания, скобки, спецсимволы)
СтрокаБезСпецсимволов = СтрЗаменитьПоРегулярномуВыражению(ИсходнаяСтрока, "\P{L}+", " ");

// Разделяем очищенную строку по пробелам, игнорируя пустые подстроки
МассивСлов = СтрРазделить(СтрокаБезСпецсимволов, " ", Ложь);

// В результате МассивСлов будет содержать: "Надо", "Разбить", "На", "Массив"

Этот способ невероятно лаконичен и занимает всего пару строк кода. Он автоматически обрабатывает буквы любых алфавитов (включая кириллицу, латиницу, диакритические знаки и т.д.), избавляя разработчика от необходимости вручную прописывать диапазоны символов.

Способ Б. Выделение слов через поиск совпадений

Если мы хотим сразу извлечь слова из строки без промежуточной замены символов, мы можем использовать функцию СтрНайтиВсеПоРегулярномуВыражению. В качестве шаблона мы укажем \p{L}+, что означает «одна или более букв любого алфавита»:


ИсходнаяСтрока = "Надо$Разбить2На/Массив)";

// Ищем все вхождения последовательностей букв
МассивРезультатов = СтрНайтиВсеПоРегулярномуВыражению(ИсходнаяСтрока, "\p{L}+");
МассивСлов = Новый Массив;

Для Каждого Результат Из МассивРезультатов Цикл
    // Результат имеет тип "РезультатПоискаПоРегулярномуВыражению"
    Слово = Сред(ИсходнаяСтрока, Результат.НачальнаяПозиция, Результат.Длина);
    МассивСлов.Добавить(Слово);
КонецЦикла;

Данный способ также является полностью кроссплатформенным и надежным, предоставляя разработчику полный контроль над процессом разбора строки.

Вариант 3. Использование функций БСП (для старых платформ без RegExp)

Если вы работаете на платформе ниже 8.3.23, но в вашей конфигурации интегрирована Библиотека Стандартных Подсистем (БСП), вы можете избежать написания собственных сложных парсеров. В БСП предусмотрены готовые функции общего назначения для работы со строками.

Например, в общем модуле СтроковыеФункцииКлиентСервер существует функция РазложитьСтрокуВМассивПодстрок. Мы можем передать в неё строку со спецсимволами, предварительно подготовив строку-разделитель из часто встречающихся знаков:


СписокРазделителей = ",./;$()[]{}*?%№+-1234567890"; // Добавляем известные спецсимволы и цифры
МассивСлов = СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок(ИсходнаяСтрока, СписокРазделителей);

Конечно, этот метод уступает регулярным выражениям в гибкости, так как вам все равно придется самостоятельно формировать перечень нежелательных символов в переменной СписокРазделителей. Тем не менее, для простых прикладных задач в рамках БСП это готовое и надежное решение.

Резюме и рекомендации

Подводя итог, выделим ключевые рекомендации по работе со спецсимволами в 1С:

← На главную