Регулярные выражения в 1С
Стас ГаниевНовый механизм платформы 8.3.23 - это возможность работы с регулярными выражениями. С одной стороны, это возможность выполнить быстрее и проще операции по поиску, замене и проверке строковых значений со сложной структурой. С другой - придется выучить еще один язык.
Задачу решить второй вопрос я и поставил перед собой в этой статье.
Чтобы вам было интереснее изучать регулярки, я попытался подобрать примеры, полезные в реальной практике 1С-ника.
Но у меня к вам просьба: накидайте в комментариях другие примеры, где можно с пользой применить новый механизм?
С помощью регулярных выражений можно выполнять три задачи:
- Проверка соответствия строки шаблону
- Поиск в строке входящих подстрок по шаблону
- Замена в строках по шаблону
В этой статье будут затронуты первые два, и начнем мы с проверки.
1 Проверка на то, что строка является идентификатором
Определение:
Идентификатор состоит из любой буквы латиницы или кириллицы, цифры и знака подчеркивания. При этом он не должен начинаться с цифры.
Решение:
В самом простом случае символы строки для сопоставления можно указывать “как есть”, перечислив их буквально. Следующий результат проверки даст Истину:
После замены любого символа получим Ложь.
Для определения соответствия массиву символов (любому символу из перечисленных) предназначены квадратные скобки (прям как в настоящем массиве), и называется это классом:
[символы]
Символы перечисляются в классе прямой подстановкой, либо в виде диапазона через тире:
- [0-9] - любая цифра;
- [a-z] - любая строчная буква латиницы;
- [0-9ABCDEFa-f] - шестнадцатиричный символ. Здесь для примера заглавные и строчные буквы указаны разными способами;
- [А-ЯЁа-яё] - любая буква кириллицы. Обратите внимание на порядок указания буквы Ё, она следует после основного алфавита в таблице кодировки Unicode.
Но это всё работает только для проверки одного символа строки. Для того, чтобы распространить проверку на другие символы, существуют операторы повторяемости:
- + - плюс, указанный после класса, означается, что условие должно выполняться для одного или более символов подряд;
- * - (звездочка) 0 и более раз;
- ? - (знак вопроса) 0 или 1 раз.
Наша проверка на символы в идентификаторе будет выглядеть следующим образом:
Буквы Ё здесь нет, т.к. ее использование в коде нарушает Стандарты разработки.
Осталось только проверить, что первый символ - не цифра. Если сейчас передать этому шаблону идентификатор 1ВидыОплаты007, мы тоже получим успешный результат, что не верно.
Остается добавить для первого символа тот же класс, только без цифр.
Итоговый вариант:
2 Проверка номера паспорта
Определение:
Номер паспорта должен состоять из 10 цифр: 4 цифры серии, попарно разделенных пробелом, затем через пробел номер из 6 цифр.
Решение:
Для начала познакомимся со спецсимволом, описывающих любую цифру:
- \d - сокращенный аналог выражения: [0-9]
А также новые операторы повторяемости, помимо перечисленных в первом примере:
- {N} - совпадение выражения ровно N раз;
- {N,} - совпадение N и более раз;
- {N,M} - совпадение от N до M раз.
Проверку номера паспорта можно выполнить с помощью любого из представленных регулярных выражений (обратите внимание на обязательное наличие пробела между классами цифр). Обе записи абсолютно равнозначны:
3 Проверка корректности имени таблицы метаданных
Определение:
Имя таблицы должно состоять из одного из ключевых слов, описывающих тип метаданного (Справочник, Документ, Отчет или Обработка), и затем через точку - идентификатор вида метаданного
Решение:
И снова введем новые определения и управляющие конструкции.
- Символ “|” (вертикальная черта) позволяет объединить условия по ИЛИ, тем самым указав, что выполняться должно одно из них;
- Для выделения логических термов выражения следует использовать круглые скобки “(“ и “)”;
Таким образом, первую часть выражения можно представить в виде:
(Справочник|Документ|Отчет|Обработка)
Круглые скобки нам нужны, чтобы последний из перечисленных вариантов не “склеился” с тем, что будет дальше.
Точка - особый символ в языке регулярок, и обозначает один любой символ.
Для того, чтобы указать саму точку, символ следует экранировать с помощью обратного слэша “\”. То есть вот так:
\.
Таким “особых” символов, требующих экранирования, существует несколько:
- * - совпадение 0 и более раз
- ? - совпадение 0 или 1 раз
- + - совпадение 1 и более раз
- [ и ] - объявление класса
- ( и ) - объявление группы
- { и } - уточнение повторяемости совпадений
- ^ - начало строки (вне класса) или отрицание (в описании класса)
- $ - конец строки
- | - условие ИЛИ
- \ - обратный слэш
- . - любоый символ
Кроме того, с помощью обратного слэша могут быть указаны так называемые метасимволы. Два из них мы уже знаем:
- \d - является десятичной цифрой: [0-9]
- \. - любой символ
Есть и другие. Вот наиболее популярные из них:
- \D - не является десятичной цифрой: [^0-9]
- \n - перенос строки: Символы.ПС
- \f - перенос страницы (формы): Сисволы.ПФ
- \r - возврат каретки: Символы.ВК
- \t - табуляция: Символы.Таб
- \s - является пробельным символом: [\t\n\f\r]
- \S - не является пробельным символом
- \uxxxx - символ с 16-ричным кодом xxxx. Например: \u0009 = Символы.Таб, \u000a = Символы.ПС
- \w - любой символ, который может входить в состав слов
- \W - символ, который не может входить в состав слов
Думаю, на первых порах другие вам и не понадобятся.
Суммируя всё вышесказанное, запишем регулярное выражение для проверки имени таблицы:
(Справочник|Документ|Отчет|Обработка)\.[А-Яа-яA-Za-z_][А-Яа-яA-Za-z_0-9]+
4 Поиск номеров заказов в назначении платежа
Наконец, мы подобрались к следующей области применения регулярных выражений - поиск фрагментов строки по шаблону.
Определение:
В поле “Назначение платежа” платежного поручения найти все номера заказов. Номер заказа - это последовательность десятичных цифр и знака тире “-”.
Решение:
Возьмем в качестве примера следующий текст:
Оплата по заказам № 99067, №87346, 12454 78-4852
Поиск подстрок работает таким образом, что в результат попадают последовательности символов до тех пор, пока они подпадают под условие регулярного выражения. То есть, если мы возьмем для поиска выражение:
[\d]
то в результате получим все возможные вхождения по одной цифре в каждом:
Чтобы получить более адекватный результат, укажем, что цифр в каждом фрагменте может быть больше одной:
Последний номер здесь разлетелся на два значения в результате, поскольку мы не указали символ тире в регулярном выражении. Исправляем недочет и получаем окончательный результат:
5 Примеры для самостоятельной проработки
Теперь, когда вы знаете основной синтаксис регулярных выражений, предлагаю вам самостоятельно решить следующие задачи:
5.1 Поиск именованных параметров в шаблоне текста
Задание:
Есть произвольный текст, содержащий идентификаторы переменных, в следующем виде:
Я, [ФамилияИмяСотрудника], с одной стороны и [НаименованиеОрганизации] с другой, вместе именуемые "Стороны", договорились:
Необходимо найти все именованные параметры в этом тексте.
Результат:
[ФамилияИмяСотрудника]
[НаименованиеОрганизации]
5.2 Места замены фрагментов текста запроса
Задание:
Получить из текста запроса именованные фрагменты для подстановки дополнительных конструкций языка.
Пример запроса:
ВЫБОР
Спр.Ссылка КАК Ссылка,
%ДопПоляВыборки%
ИЗ
Справочник.Номенклатура КАК Спр
ГДЕ
НЕ Спр.ПометкаУдаления
И НЕ Спр.ЭтоГруппа
%ДопУсловиия%
Результат:
%ДопПоляВыборки%
%ДопУсловиия%
5.3 Поиск тегов в HTML-тексте
Задание:
Полезная функция для динамического управления текстом HTML-документа.Теги в тексте могут быть представлены в двух вариантах:
Самозакрывающийся:
<ИмяТега СтрокаПараметров\>
С парным закрывающим тегом:
<ИмяТега СтрокаПараметров>
// произвольный контент
<\ИмяТега>
Синтаксис языка HTML допускает произвольный перенос строк в любом месте текста и использование в качестве пробелов произвольное число пробелов, табуляций и переносов строк в произвольной последовательности.
Попробуйте составить регулярное выражение по поиску областей действия тега в таком тексте.