С выходом новых версий платформы 1С:Предприятие (начиная с 8.3.23) разработчики получили долгожданный инструмент — нативные функции для работы с регулярными выражениями. Однако многие специалисты сталкиваются с ситуацией, когда функции (например, СтрЗаменитьПоРегулярномуВыражению) доступны в коде и работают, но при попытке открыть справку (F1) Синтаксис-помощник не выдает никакой информации. Давайте разберем, почему это происходит, как исправить отображение справки и, самое главное, подробно рассмотрим, как пользоваться этими инструментами.
Ситуация, когда платформа обновлена, а справка "молчит", встречается нередко. Рассмотрим основные причины и способы их устранения.
Попробуйте проверить настройки платформы. Перейдите в меню Сервис — Параметры — Справка. Убедитесь, что не установлены ограничивающие фильтры. В некоторых случаях (хоть это и кажется нелогичным для новых функций) помогает галочка "Отображать нерекомендуемые объекты" или сброс настроек фильтрации.
Ранее для работы с регулярными выражениями (RegExp) программисты 1С вынуждены были использовать COM-объект VBScript.RegExp. У этого подхода были недостатки: работа только под Windows и зависимость от внешних компонентов.
Начиная с версии 8.3.23, платформа использует библиотеку ICU (International Components for Unicode). Давайте проанализируем, что это значит для нас как для разработчиков:
[a-zA-Zа-яА-Я] можно использовать \p{L}, что означает "любая буква любого алфавита".Разберем детально синтаксис и применение новых функций. Их всего две основные, но они покрывают большинство задач.
Функция ищет первое вхождение шаблона в строке. Если вам нужно найти все вхождения, придется организовывать цикл, смещая позицию поиска.
Синтаксис:
Результат = СтрНайтиПоРегулярномуВыражению(ИсходнаяСтрока, Шаблон, [НаправлениеПоиска], [НачальнаяПозиция], [НомерВхождения]);
Функция возвращает объект типа РезультатПоискаПоРегулярномуВыражению или Неопределено, если ничего не найдено. Рассмотрим свойства возвращаемого объекта:
Значение — сама найденная подстрока.НачальнаяПозиция — индекс начала (начинается с 1).Длина — количество символов в найденной подстроке.Группы — коллекция захваченных групп (если в шаблоне использовались скобки).Пример использования: Допустим, нам нужно извлечь артикул вида "ABC-1234" из текста.
Текст = "Поступил товар с артикулом ABC-1234 на склад.";
Шаблон = "[A-Z]{3}-\d{4}";
Попытка
РезультатПоиска = СтрНайтиПоРегулярномуВыражению(Текст, Шаблон);
Если РезультатПоиска <> Неопределено Тогда
Сообщить("Найден артикул: " + РезультатПоиска.Значение); // Выведет: ABC-1234
Сообщить("Позиция: " + РезультатПоиска.НачальнаяПозиция);
Иначе
Сообщить("Артикул не найден.");
КонецЕсли;
Исключение
Сообщить("Ошибка в шаблоне: " + ОписаниеОшибки());
КонецПопытки;
Обратите внимание на использование блока Попытка ... Исключение. Если в шаблоне будет синтаксическая ошибка (например, незакрытая скобка), платформа сгенерирует исключение. Это критически важно учитывать при формировании шаблонов динамически.
Эта функция позволяет заменить все вхождения, соответствующие шаблону, на строку замены. Поддерживается использование ссылок на захваченные группы ($1, $2 и т.д.).
Синтаксис:
НоваяСтрока = СтрЗаменитьПоРегулярномуВыражению(ИсходнаяСтрока, Шаблон, СтрокаЗамены);
Пример с перестановкой слов: Поменяем местами Фамилию и Имя.
ФИО = "Иванов Иван";
// Шаблон ищет два слова, разделенных пробелом.
// (\w+) - захватывает слово в группу 1
// \s+ - один или более пробелов
// (\w+) - захватывает второе слово в группу 2
Шаблон = "(\w+)\s+(\w+)";
// $2 ссылается на вторую группу (Имя), $1 на первую (Фамилия)
Результат = СтрЗаменитьПоРегулярномуВыражению(ФИО, Шаблон, "$2 $1");
Сообщить(Результат); // Выведет: Иван Иванов
Как мы упоминали ранее, отдельных параметров для флагов нет. Используйте инлайн-модификаторы в начале шаблона.
(?i) — Игнорировать регистр (Case Insensitive).(?m) — Многострочный режим (Multine). Символы ^ и $ будут совпадать с началом и концом каждой строки, а не всего текста.(?s) — Точка соответствует переводу строки (Single line).Пример поиска без учета регистра:
Текст = "Важный документ";
// Без флага (?i) слово "важный" с маленькой буквы не нашлось бы
Шаблон = "(?i)важный";
Если СтрНайтиПоРегулярномуВыражению(Текст, Шаблон) <> Неопределено Тогда
Сообщить("Найдено!");
КонецЕсли;
Коллекция Группы в объекте результата поиска позволяет детально разобрать строку. Рассмотрим пример парсинга строки адреса электронной почты, чтобы отделить логин от домена.
Email = "user@example.com";
// Шаблон с двумя группами: (логин)@(домен)
Шаблон = "([a-zA-Z0-9_.]+)@([a-zA-Z0-9_.]+)";
Результат = СтрНайтиПоРегулярномуВыражению(Email, Шаблон);
Если Результат <> Неопределено Тогда
// Группы индексируются с 0.
// Группа[0] - это все совпадение целиком ("user@example.com")
// Группа[1] - первая скобка (логин)
// Группа[2] - вторая скобка (домен)
Логин = Результат.Группы.Получить(1).Значение;
Домен = Результат.Группы.Получить(2).Значение;
Сообщить("Логин: " + Логин);
Сообщить("Домен: " + Домен);
КонецЕсли;
Давайте проанализируем вопросы производительности при использовании новых функций:
VBScript.RegExp, так как нет затрат на маршалинг данных (передачу между процессом 1С и COM-объектом). Это особенно заметно при большом количестве вызовов в цикле.СтрЗаменить или СтрНайти (например, простая замена "Маша" на "Даша"), то стандартные строковые функции будут работать быстрее. Используйте регулярные выражения там, где есть сложные шаблоны поиска.Попытка, если шаблон вводит пользователь или он формируется программно, чтобы избежать падения приложения.Используя эти знания, вы сможете эффективно применять мощь библиотеки ICU в своих решениях на платформе 1С, даже если Синтаксис-помощник временно не отображает подсказки по этим методам.