Регулярные выражения 1С встроены в платформу с версии 8.3.23: проверить ИНН, вытащить из назначения платежа все номера счетов или почистить телефон можно одной строкой, без COM-объектов и циклов по символам. Ниже — функции платформы, поиск всех вхождений с группами, замена и варианты для старых релизов.
Через СтрНайти и Сред в цикле это тоже решается, но код выходит длинным и ломается на первом нестандартном написании. Регулярное выражение описывает формат целиком, правило меняется в одной строке.
Отдельного объекта для регулярок нет. Работа с регулярными выражениями в 1С идёт через функции глобального контекста:
| Функция | Что делает | Что возвращает |
|---|---|---|
СтрПодобнаПоРегулярномуВыражению(ИсходнаяСтрока, РегулярноеВыражение, [ИгнорироватьРегистр], [МногострочныйПоиск]) | проверяет строку на соответствие шаблону | Булево |
СтрНайтиПоРегулярномуВыражению(ИсходнаяСтрока, РегулярноеВыражение, [НаправлениеПоиска], [НачальнаяПозиция], [НомерВхождения], [ИгнорироватьРегистр], [МногострочныйПоиск]) | ищет одно вхождение, по умолчанию первое | РезультатПоискаПоРегулярномуВыражению; если ничего не нашлось, НачальнаяПозиция = 0 |
СтрНайтиВсеПоРегулярномуВыражению(ИсходнаяСтрока, РегулярноеВыражение, [ИгнорироватьРегистр], [МногострочныйПоиск]) | находит все вхождения | Массив результатов поиска |
СтрЗаменитьПоРегулярномуВыражению(ИсходнаяСтрока, РегулярноеВыражение, ПодстрокаЗамены, [ИгнорироватьРегистр], [МногострочныйПоиск]) | заменяет все найденные фрагменты | Строка |
Параметры в квадратных скобках необязательные, ИгнорироватьРегистр и МногострочныйПоиск по умолчанию равны Ложь. Направление, начальная позиция и номер вхождения есть только у СтрНайтиПоРегулярномуВыражению. Вместо булевых параметров можно поставить флаги (?i) и (?m) в сам шаблон — в примерах ниже сделано так.
У результата поиска есть свойства НачальнаяПозиция (счёт с 1, как в Сред), Длина, Значение и метод ПолучитьГруппы() — массив скобочных групп с теми же свойствами.
&НаСервереБезКонтекста
Функция НомерОтправления(Знач Комментарий)
// Первое число из 10 и более цифр подряд
Результат = СтрНайтиПоРегулярномуВыражению(Комментарий, "[0-9]{10,}");
Если Результат.НачальнаяПозиция = 0 Тогда
Возврат ""; // совпадений нет
КонецЕсли;
Возврат Результат.Значение;
КонецФункции
Что учесть:
&НаКлиенте) их нет. В модуле формы вызывайте их из &НаСервере или &НаСервереБезКонтекста, общий модуль — с флагом «Сервер».\d, \w, \s, квантификаторы {n,m}, ленивые *?, незахватывающие группы (?:…), просмотр вперёд и назад, флаги (?i), (?m), (?s). Классы юникодные: кириллица входит в \w без настроек, а \d пропускает не только 0–9, но и, например, полноширинные цифры.\d пишется без удвоения, в отличие от C# и JavaScript. Удваивать нужно только кавычку: «текст в кавычках» — это """[^""]*""".Самый частый сценарий — найти по регулярному выражению в 1С все фрагменты и разобрать каждый на части. Пример: достать из назначения платежа все счета вида «по счету № 125 от 05.09.2026». Функция НайтиВсеВхождения в серверном общем модуле возвращает массив структур: остальной код не зависит от платформенного типа результата, а массив можно передать на клиент.
// Общий модуль РегулярныеВыраженияСервер, флаг «Сервер».
// Платформа 8.3.23 и новее, режим совместимости не ниже 8.3.23.
// Находит все вхождения шаблона в тексте.
// Возвращает массив структур:
// Значение - Строка - найденный фрагмент целиком;
// Позиция - Число - позиция первого символа, счёт с 1;
// Группы - Массив - тексты скобочных групп по порядку: [0] = $1, [1] = $2 и т.д.
//
Функция НайтиВсеВхождения(Знач Текст, Знач Шаблон) Экспорт
Результат = Новый Массив;
Для Каждого Совпадение Из СтрНайтиВсеПоРегулярномуВыражению(Текст, Шаблон) Цикл
Группы = Новый Массив;
Для Каждого Группа Из Совпадение.ПолучитьГруппы() Цикл
Группы.Добавить(Группа.Значение);
КонецЦикла;
Вхождение = Новый Структура;
Вхождение.Вставить("Значение", Совпадение.Значение);
Вхождение.Вставить("Позиция", Совпадение.НачальнаяПозиция);
Вхождение.Вставить("Группы", Группы);
Результат.Добавить(Вхождение);
КонецЦикла;
Возврат Результат;
КонецФункции
// Все счета из назначения платежа вида
// «по счету № 125 от 05.09.2026, сч. А-17 от 06.09.2026».
// Возвращает таблицу значений с колонками Номер (Строка) и Дата (Дата).
//
Функция СчетаИзНазначенияПлатежа(Знач НазначениеПлатежа) Экспорт
// группа 1 - номер счета, 2 - день, 3 - месяц, 4 - год
Шаблон = "(?i)\bсч(?:[её]т[уа]?)?(?:\b|\.)\s*(?:№|N)?\s*(\w[\w/-]*)\s+от\s+(\d{2})\.(\d{2})\.(\d{4})";
Счета = Новый ТаблицаЗначений;
Счета.Колонки.Добавить("Номер", Новый ОписаниеТипов("Строка"));
Счета.Колонки.Добавить("Дата", Новый ОписаниеТипов("Дата"));
Для Каждого Вхождение Из НайтиВсеВхождения(НазначениеПлатежа, Шаблон) Цикл
НоваяСтрока = Счета.Добавить();
НоваяСтрока.Номер = Вхождение.Группы[0];
Попытка
НоваяСтрока.Дата = Дата(Число(Вхождение.Группы[3]),
Число(Вхождение.Группы[2]), Число(Вхождение.Группы[1]));
Исключение
// «31.02.2026» проходит по шаблону, но датой не является:
// номер сохраняем, дату оставляем пустой
КонецПопытки;
КонецЦикла;
Возврат Счета;
КонецФункции
// Пример вызова:
// Счета = РегулярныеВыраженияСервер.СчетаИзНазначенияПлатежа(
// "Оплата по счету № 125 от 05.09.2026, сч. А-17 от 06.09.2026. Без НДС");
// Результат: две строки - «125» от 05.09.2026 и «А-17» от 06.09.2026.
СтрНайтиВсеПоРегулярномуВыражению без совпадений возвращает пустой массив, проверять на Неопределено не нужно.ПолучитьГруппы() отдаёт захватывающие группы в порядке открывающих скобок: первая скобка — это Группы[0] в нашем массиве и $1 в строке замены. Скобки (?:…) группу не создают, ими удобно объединять варианты написания.(?i) отключает учёт регистра: «Счет», «СЧЕТ» и «сч.» найдутся одинаково.\b в начале — граница слова, иначе «расчет № 5 от 01.09.2026» распознался бы как счёт.(?:\b|\.) требует, чтобы после «сч», «счет», «счету» слово закончилось или стояла точка сокращения, а \w[\w/-]* — чтобы номер начинался с буквы или цифры: «125», «А-17», «17/2». Без этих условий «Оплата по счету от 05.09.2026» дала бы номер «у», а «Счет-фактура от 05.09.2026» — номер «-фактура».Попытка: шаблон гарантирует две цифры, а не существующий день, и «31.02.2026» без обработки исключения остановило бы загрузку выписки.Структуру, в отличие от платформенного результата поиска, можно вернуть на клиент. Подробнее — про структуры и таблицы значений.
Для проверки строки целиком используйте СтрПодобнаПоРегулярномуВыражению и ставьте якоря ^ и $: тогда шаблон ведёт себя одинаково и в функциях поиска, где без якорей он совпадёт с частью строки.
// Общий модуль РегулярныеВыраженияСервер (продолжение).
Функция ФорматИННВерный(Знач ИНН) Экспорт
Возврат СтрПодобнаПоРегулярномуВыражению(СокрЛП(ИНН), "^([0-9]{10}|[0-9]{12})$");
КонецФункции
Функция ФорматПочтыВерный(Знач Адрес) Экспорт
Возврат СтрПодобнаПоРегулярномуВыражению(СокрЛП(Адрес), "^[^@\s]+@[^@\s]+\.[^@\s]{2,}$");
КонецФункции
| Что проверяем | Шаблон | Комментарий |
|---|---|---|
| ИНН | ^([0-9]{10}|[0-9]{12})$ | 10 цифр — организация, 12 — ИП и физлицо. Контрольные цифры регулярка не проверяет |
| КПП | ^[0-9]{4}[0-9A-Z]{2}[0-9]{3}$ | 5-й и 6-й символы — цифры или заглавные латинские буквы |
| БИК | ^04[0-9]{7}$ | российские БИК начинаются с 04 |
| ОГРН / ОГРНИП | ^([0-9]{13}|[0-9]{15})$ | 13 цифр — организация, 15 — ИП |
| СНИЛС | ^[0-9]{3}-[0-9]{3}-[0-9]{3} [0-9]{2}$ | с разделителями; без них — ^[0-9]{11}$ |
^[^@\s]+@[^@\s]+\.[^@\s]{2,}$ | грубая проверка «есть @ и домен»; полную проверку по RFC регуляркой не делают | |
| Телефон РФ | ^\+7[0-9]{10}$ | после нормализации (см. ниже) |
| Дата ДД.ММ.ГГГГ | ^[0-9]{2}\.[0-9]{2}\.[0-9]{4}$ | проверяет формат, а не существование даты |
Для реквизитов пишем [0-9], а не \d: ИНН из «нелатинских» цифр Юникода прошёл бы проверку формата, а потом сломал бы поиск по базе и обмен.
Обработка строк регулярными выражениями в 1С чаще всего сводится к чистке. СтрЗаменитьПоРегулярномуВыражению меняет все вхождения, а не первое. В строке замены $0 — вся найденная подстрока, $1, $2 и далее — группы, а сам знак доллара экранируется: \$.
// Оставляет только цифры и приводит российский номер к виду +7XXXXXXXXXX.
// Если номер не распознан, возвращает пустую строку.
Функция НормализованныйТелефон(Знач Телефон) Экспорт
Цифры = СтрЗаменитьПоРегулярномуВыражению(Телефон, "[^0-9]", "");
Если СтрДлина(Цифры) = 11 И (Лев(Цифры, 1) = "7" Или Лев(Цифры, 1) = "8") Тогда
Возврат "+7" + Сред(Цифры, 2);
ИначеЕсли СтрДлина(Цифры) = 10 Тогда
Возврат "+7" + Цифры;
КонецЕсли;
Возврат "";
КонецФункции
// «05.09.2026» -> «2026-09-05» во всём тексте за один вызов.
Функция ДатыВФорматеISO(Знач Текст) Экспорт
Возврат СтрЗаменитьПоРегулярномуВыражению(Текст, "\b(\d{2})\.(\d{2})\.(\d{4})\b", "$3-$2-$1");
КонецФункции
// Двойные пробелы, табуляции и переносы строк -> один пробел.
Функция СхлопнутьПробелы(Знач Текст) Экспорт
Возврат СокрЛП(СтрЗаменитьПоРегулярномуВыражению(Текст, "\s+", " "));
КонецФункции
[^0-9] — любой символ, кроме цифр 0–9: «8 (912) 345-67-89» превращается в «89123456789», а дальше хватает проверки длины и первой цифры. Чтобы превратить найденный текст в значение даты, пригодится статья про формат даты в 1С.
В тонком и веб-клиенте функций регулярных выражений нет, поэтому проверку на форме делаем серверным вызовом без контекста: форма на сервер не передаётся. Если у общего модуля стоит ещё и флаг «Вызов сервера», его функцию можно вызвать с клиента напрямую.
&НаКлиенте
Процедура ИННПриИзменении(Элемент)
Если Не ЗначениеЗаполнено(Объект.ИНН) Тогда
Возврат;
КонецЕсли;
Если Не ФорматИННВерныйНаСервере(Объект.ИНН) Тогда
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "ИНН должен состоять из 10 или 12 цифр";
Сообщение.Поле = "ИНН";
Сообщение.ПутьКДанным = "Объект";
Сообщение.Сообщить();
КонецЕсли;
КонецПроцедуры
&НаСервереБезКонтекста
Функция ФорматИННВерныйНаСервере(Знач ИНН)
Возврат РегулярныеВыраженияСервер.ФорматИННВерный(ИНН);
КонецФункции
Тысячу строк так не проверяют: соберите их в массив и отправьте на сервер одним вызовом.
На 8.3.22 и ниже встроенных функций нет, и поиск по регулярным выражениям в 1С собирают из подручных средств. Рабочих вариантов два.
В XML Schema у строкового типа есть фасет pattern — регулярное выражение. Собираем на лету схему с таким типом и создаём значение: если строка не подходит, платформа выбрасывает исключение.
// Проверка строки по шаблону XML Schema: любой релиз 8.3, сервер Windows или Linux.
// Шаблон всегда сравнивается со строкой ЦЕЛИКОМ, ^ и $ не пишем.
&НаСервереБезКонтекста
Функция СоответствуетШаблонуXSD(Знач Текст, Знач Шаблон)
// Шаблон попадает в XML-атрибут, поэтому экранируем спецсимволы XML
ШаблонXML = СтрЗаменить(Шаблон, "&", "&");
ШаблонXML = СтрЗаменить(ШаблонXML, "<", "<");
ШаблонXML = СтрЗаменить(ШаблонXML, """", """);
ТекстСхемы =
"<xs:schema xmlns:xs=""http://www.w3.org/2001/XMLSchema"" targetNamespace=""urn:regex-check"">
| <xs:simpleType name=""Check"">
| <xs:restriction base=""xs:string"">
| <xs:pattern value=""" + ШаблонXML + """/>
| </xs:restriction>
| </xs:simpleType>
|</xs:schema>";
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.УстановитьСтроку(ТекстСхемы);
ПостроительDOM = Новый ПостроительDOM;
ДокументDOM = ПостроительDOM.Прочитать(ЧтениеXML);
ЧтениеXML.Закрыть();
ПостроительСхем = Новый ПостроительСхемXML;
СхемаXML = ПостроительСхем.СоздатьСхемуXML(ДокументDOM.ЭлементДокумента);
НаборСхем = Новый НаборСхемXML;
НаборСхем.Добавить(СхемаXML);
Фабрика = Новый ФабрикаXDTO(НаборСхем);
ТипПроверки = Фабрика.Тип("urn:regex-check", "Check");
Попытка
Фабрика.Создать(ТипПроверки, Текст);
Исключение
Возврат Ложь; // значение не прошло фасет pattern
КонецПопытки;
Возврат Истина;
КонецФункции
// Вызов: СоответствуетШаблонуXSD("1234567890", "[0-9]{10}|[0-9]{12}") -> Истина
Способ работает под Windows и Linux без внешних компонент, но умеет только «да/нет»: ни поиска вхождений, ни замены. Диалект XML Schema беднее ICU — нет ленивых квантификаторов, просмотра вперёд и флага регистра. Схема собирается на каждый вызов, поэтому при массовой проверке создайте фабрику и тип один раз.
Способ из старых обработок. Типа «Новый РегулярноеВыражение» в платформе нет, объект создаётся через Новый COMОбъект("VBScript.RegExp").
// Только если код исполняется под Windows: на Windows-сервере 1С функция
// работает при любом клиенте, в том числе веб. На сервере Linux - нет.
&НаСервереБезКонтекста
Функция НайтиВсеЧерезVBScript(Знач Текст, Знач Шаблон)
Результат = Новый Массив;
Выражение = Новый COMОбъект("VBScript.RegExp");
Выражение.Pattern = Шаблон;
Выражение.Global = Истина; // без этого Execute вернёт только первое совпадение
Выражение.IgnoreCase = Истина;
Выражение.MultiLine = Истина;
Совпадения = Выражение.Execute(Текст);
Для Индекс = 0 По Совпадения.Count - 1 Цикл
Совпадение = Совпадения.Item(Индекс);
Группы = Новый Массив;
Для НомерГруппы = 0 По Совпадение.SubMatches.Count - 1 Цикл
Группы.Добавить(Совпадение.SubMatches.Item(НомерГруппы));
КонецЦикла;
Вхождение = Новый Структура;
Вхождение.Вставить("Значение", Совпадение.Value);
Вхождение.Вставить("Позиция", Совпадение.FirstIndex + 1); // в VBScript счёт с нуля
Вхождение.Вставить("Группы", Группы);
Результат.Добавить(Вхождение);
КонецЦикла;
Возврат Результат;
КонецФункции
Нужна Windows с включённым VBScript там, где исполняется код: серверная функция на Windows-сервере доступна из любого клиента, включая веб, а на сервере Linux способ отпадает. Диалект как в старом JavaScript — без просмотра назад и именованных групп. Microsoft объявила VBScript устаревшим компонентом Windows, на новых серверах он может оказаться отключён, так что это решение до перехода на 8.3.23.
&НаКлиенте, общий модуль с флагом «Клиент (управляемое приложение)»).Новый РегулярноеВыражение по аналогии с другими языками. Такого типа нет, есть только функции.[0-9]{10} найдёт «ИНН» внутри строки из 14 цифр. Для проверки формата ставьте ^ и $.\d{2}.\d{2}.\d{4} пропустит «05/09/2026»: точка означает любой символ, нужно \..""".*""" в строке с несколькими парами кавычек захватит всё от первой до последней. Используйте ленивый .*? или класс [^""]*.^ и $ означают начало и конец всего текста, а точка не совпадает с переводом строки. Для построчной обработки передайте МногострочныйПоиск = Истина или поставьте в шаблон флаг (?m). Чтобы точка захватывала перевод строки, нужен флаг (?s).VBScript.RegExp: код выполняется на сервере под Linux или в Windows, где VBScript отключён. В клиентском коде веб-клиента COM-объектов нет вовсе.^ и $ в XDTO-шаблоне. В XML Schema это обычные символы: шаблон ^[0-9]{10}$ не совпадёт ни с одним ИНН. Якоря не нужны, шаблон и так сравнивается со строкой целиком.С 8.3.23, причём режим совместимости конфигурации тоже должен быть не ниже 8.3.23 (или «Не использовать»). На доработанных базах это частая ловушка: платформу обновили, а режим остался старым.
В управляемом приложении — нет: в тонком клиенте, веб-клиенте и процедурах &НаКлиенте этих функций нет. Проверку на форме делайте серверной функцией без контекста, как в примере выше. В конфигурациях на БСП для простых клиентских проверок есть СтроковыеФункцииКлиентСервер.ТолькоЦифрыВСтроке() и ОбщегоНазначенияКлиентСервер.АдресЭлектроннойПочтыСоответствуетТребованиям() — сверьте их с версией своей БСП.
Нет, в тексте запроса их не вызвать. Там есть ПОДОБНО с %, _, [диапазон] и [^диапазон] — для «начинается с цифры» хватает. Сложные условия проверяют в два шага: запрос отбирает кандидатов, регулярка на сервере — окончательно.
Для простых задач: «содержит подстроку», «начинается с», «разбить по запятой» — СтрНайти, СтрНачинаетсяС и СтрРазделить быстрее и понятнее. Регулярка окупается, когда формат вариативный: разные написания, необязательные части, несколько вхождений с группами.
Разбор банковских выписок, комментариев к заказам или прайсов поставщиков с «творческим» заполнением, когда на отладку шаблонов нет времени, — задача для доработки отчётов и обработок 1С. Опишите задачу и приложите несколько примеров строк на странице «Разместить задание»: оценка бесплатная, ответ — в течение рабочего дня.
Станьте частью сообщества!
Войдите или зарегистрируйтесь, и вы сможете участвовать в обсуждениях.