Как извлечь текст из середины строки, удалив 4 цифры в начале и в конце в 1С?

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

В практике программиста 1С часто возникают задачи по обработке входящих строк, имеющих фиксированную структуру. Типичный пример: строка начинается с уникального четырехзначного префикса, содержит полезную информацию в середине и заканчивается четырехзначным кодом. Наша задача — эффективно извлечь «средний кусок», отбросив лишние цифровые символы по краям. Рассмотрим, как это можно сделать, используя современные и классические инструменты платформы 1С.

Анализ структуры регулярного выражения

Для начала разберем сам шаблон (паттерн) регулярного выражения, который поможет нам идентифицировать нужные части строки. Если исходная строка имеет вид "1234тут белиберда идет 9765", нам необходимо определить правила для поиска начала, середины и конца.

Проанализируем основные элементы шаблона:

  1. ^[\d]{4} — этот фрагмент ищет ровно 4 цифры ([\d]{4}) строго в начале строки (символ ^).
  2. (.*) — это «захватывающая группа». Точка означает любой символ, а звездочка — любое количество повторений. Скобки позволяют нам сохранить найденное содержимое для последующего использования.
  3. [\d]{4}$ — этот фрагмент ищет 4 цифры в конце строки (символ $).

Давайте разберем по шагам, какие методы реализации этой задачи существуют в среде 1С, учитывая эволюцию платформы.

Способ 1. Современный подход (Платформа 8.3.24 и выше)

Начиная с версии 8.3.24, в платформе 1С появилась встроенная поддержка регулярных выражений, которая работает на движке ICU. Это кардинально меняет подход, так как теперь нам не нужно использовать тяжелые внешние компоненты или COM-объекты Windows. Новый движок поддерживает механизмы «просмотра вперед» и «просмотра назад» (look-ahead и look-behind).

Рассмотрим пример кода, использующий объект РегулярноеВыражение:


// Создаем объект регулярного выражения
РегВыр = Новый РегулярноеВыражение("(?<=^\d{4}).*(?=\d{4}$)");

// Исходная строка
Стр = "1234тут белиберда идет 9765";

// Поиск соответствия
РезультатПоиска = РегВыр.НайтиВТексте(Стр);

Если РезультатПоиска.Количество() > 0 Тогда
    СреднийКусок = РезультатПоиска[0].Значение;
    Сообщить("Результат: " + СреднийКусок);
КонецЕсли;

В этом примере мы использовали конструкцию (?<=...) — ретроспективную проверку (просмотр назад) и (?=...) — опережающую проверку. Это позволяет нам найти текст, который окружен цифрами, не включая сами цифры в результат поиска. Это самый элегантный способ, доступный в современных версиях 1С.

Способ 2. Использование захватывающих групп (Capturing Groups) в COM-объекте

Если ваша информационная база работает на более старых версиях платформы, мы вынуждены использовать объект VBScript.RegExp. В этом объекте отсутствует полноценная поддержка ретроспективной проверки (look-behind), поэтому мы не можем просто «отсечь» края. Однако мы можем захватить середину в группу.

Рассмотрим, как прочитать содержимое группы в коде 1С:


// Инициализация COM-объекта
RegExp = Новый COMОбъект("VBScript.RegExp");
RegExp.IgnoreCase = Истина;
RegExp.Global = Ложь; // Нам нужно только одно вхождение (вся строка)
RegExp.Pattern = "^\d{4}(.*)\d{4}$";

ИсходнаяСтрока = "1234тут белиберда идет 9765";

Matches = RegExp.Execute(ИсходнаяСтрока);

Если Matches.Count > 0 Тогда
    // Обращаемся к первой захваченной группе (SubMatches)
    СреднийКусок = Matches.Item(0).SubMatches.Item(0);
    Сообщить("Извлеченный текст: '" + СреднийКусок + "'");
КонецЕсли;

Важный момент: в этом шаблоне (.*) является «жадным» квантификатором. Если внутри «белиберды» встретятся еще цифры, он захватит их. Если вам нужно гарантировать, что отсекаются только крайние 4 цифры, а внутри могут быть свои цифровые блоки, шаблон останется прежним, так как привязка ^ и $ жестко фиксирует края строки.

Способ 3. Метод замены (Replace) с обратными ссылками

Еще один эффективный метод — использование функции Replace. Вместо того чтобы «искать» кусок, мы можем заменить всю строку на её центральную часть. Для этого используются обратные ссылки (back-references).

Проанализируем этот алгоритм:


RegExp = Новый COMОбъект("VBScript.RegExp");
RegExp.Pattern = "^\d{4}(.*)\d{4}$";

ИсходнаяСтрока = "1234тут белиберда идет 9765";

// $1 — это ссылка на содержимое первой скобочной группы (.*)
Результат = RegExp.Replace(ИсходнаяСтрока, "$1");

Сообщить(Результат); // Выведет: "тут белиберда идет "

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

Способ 4. Использование встроенных строковых функций 1С (Самый быстрый)

Не стоит забывать, что регулярные выражения — это мощный, но ресурсоемкий инструмент. Если условие задачи всегда фиксировано (ровно 4 символа в начале и ровно 4 в конце), использование объекта VBScript.RegExp будет избыточным.

Давайте выясним причину, почему строковые функции могут быть предпочтительнее. Инициализация COM-объекта занимает время, а парсинг шаблона нагружает процессор. Если обработка идет в цикле по тысячам строк, стандартные функции 1С справятся быстрее в десятки раз.

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


ИсходнаяСтрока = "1234тут белиберда идет 9765";

// Проверяем длину строки, чтобы не получить ошибку
Если СтрДлина(ИсходнаяСтрока) >= 8 Тогда
    // Начинаем с 5-го символа (пропускаем 4 цифры)
    // Длина извлекаемого куска = Общая длина минус 4 (начало) и минус 4 (конец)
    Результат = Сред(ИсходнаяСтрока, 5, СтрДлина(ИсходнаяСтрока) - 8);
КонецЕсли;

Преимущества этого метода:

  1. Высокая производительность.
  2. Отсутствие зависимости от внешних библиотек.
  3. Код легко читается даже начинающими разработчиками.

Нюансы «жадности» и проверки данных

При использовании регулярных выражений важно учитывать поведение операторов. В примере ^\d{4}(.*)\d{4}$ точка со звездочкой по умолчанию является «жадной». Это значит, что если ваша строка выглядит как "1234 5678 текст 1234 5678", то жадный оператор постарается захватить максимально возможную область между первым и последним совпадением.

Если же ваша логика требует найти минимальный кусок текста между цифрами, используйте «ленивый» квантификатор: (.*?). Однако при наличии жестких привязок к началу (^) и концу ($) строки, в данной конкретной задаче разницы в результате не будет, так как границы строки четко определены.

Перед тем как извлекать данные, мы рекомендуем всегда проводить валидацию. В случае с регулярками это метод Test():


Если RegExp.Test(ИсходнаяСтрока) Тогда
    // Обрабатываем...
Иначе
    Сообщить("Строка не соответствует формату (4 цифры в начале и конце)");
КонецЕсли;

Подведение итогов

Мы рассмотрели несколько способов решения задачи. Выбор конкретного метода зависит от вашей версии платформы и требований к производительности:

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

← На главную