Работа с текстовыми данными в системе 1С:Предприятие является одной из самых частых задач для разработчика. Будь то очистка пользовательского ввода от лишних символов, форматирование названий номенклатуры или подготовка данных для выгрузки в XML, умение манипулировать строками критически важно.
В отличие от некоторых других языков программирования, где существует единая мощная функция для вырезания текста по шаблону, в 1С подход часто требует комбинации нескольких стандартных процедур. Разработчик должен четко понимать разницу между простой заменой символов и сложным анализом структуры строки.
В данной статье мы детально разберем алгоритмы удаления подстрок. Мы рассмотрим как простые случаи с фиксированным текстом, так и сложные сценарии с использованием регулярных выражений, обеспечивая максимальную производительность вашего кода.
Стандартная функция СтрЗаменить как основной инструмент
Самый очевидный и часто используемый способ удалить часть текста — это функция СтрЗаменить. Она заменяет все вхождения одной подстроки на другую. Если ваша цель — удаление, то в качестве замены вы указываете пустую строку.
Этот метод идеален, когда вам нужно избавиться от повторяющихся символов или слов, разбросанных по всему тексту. Например, удаление всех пробелов из номера телефона или удаление маркеров валюты из строки суммы.
Функция является регистрозависимой, что означает, что "Текст" и "текст" для нее — разные сущности. Это важно учитывать при обработке данных, введенных пользователями в произвольном регистре.
ИсходнаяСтрока = "Цена: 100 руб., Налог: 20 руб.";
// Удаляем слово "руб." везде, где оно встречается
ОчищеннаяСтрока = СтрЗаменить(ИсходнаяСтрока, " руб.", "");
// Результат: "Цена: 100, Налог: 20"
Однако стоит помнить, что СтрЗаменить удаляет все вхождения. Если в тексте слово, которое вы хотите удалить, встречается в другом контексте, где его трогать нельзя, этот метод приведет к порче данных.
⚠️ Внимание: Функция
СтрЗаменитьсоздает новую строку в памяти. При обработке огромных массивов данных в цикле это может привести к значительному потреблению оперативной памяти и замедлению работы системы.
Если вам нужно удалить только первое вхождение подстроки, используйте комбинацию СтрНайти и СтрЛев/СтрПрав, так как СтрЗаменить не имеет параметра "количество замен".
Удаление фиксированной части в начале или конце строки
Часто возникает задача удалить префикс или суффикс, если они присутствуют. Например, при загрузке файлов из Excel названия колонок могут содержать лишние пробелы или служебные символы в начале.
Для этих целей в платформе 1С существуют специализированные функции СтрНачинаетсяС и СтрЗаканчиваетсяНа. Они возвращают булево значение, позволяя принять решение об обрезке.
- 🔍 Используйте
СтрЛевдля получения части строки слева. - ✂️ Используйте
СтрПравдля получения части строки справа. - 📏 Используйте
СтрДлинадля вычисления новой длины строки после удаления.
Алгоритм выглядит следующим образом: сначала мы проверяем наличие нежелательной подстроки на краю. Если проверка успешна, мы вычисляем новую длину и вырезаем нужную часть, игнорируя удаляемый фрагмент.
Текст = "/tmp/cache/file.dat";
Префикс = "/tmp/";
Если СтрНачинаетсяС(Текст, Префикс) Тогда
// Вычисляем длину остающейся части
НоваяДлина = СтрДлина(Текст) - СтрДлина(Префикс);
// Берем правую часть, отбрасывая префикс
Текст = СтрПрав(Текст, НоваяДлина);
КонецЕсли;
Важно отметить, что попытка обрезать строку, используя отрицательную длину или длину большую, чем есть в наличии, приведет к ошибке выполнения. Всегда проверяйте длину перед операцией.
☑️ Алгоритм безопасной обрезки
Вырезание текста между разделителями
Более сложная задача — удаление фрагмента, находящегося внутри строки между двумя известными маркерами. Классический пример: удаление комментариев в коде или очистка HTML-тегов из описания товара.
Здесь нам на помощь приходит функция СтрНайти. Она позволяет определить позицию начала искомой подстроки. Комбинируя два поиска (начала и конца блока), мы можем точно вычислить, что нужно вырезать.
| Функция | Назначение | Возвращаемое значение |
|---|---|---|
СтрНайти |
Поиск подстроки | Позиция (число) или 0 |
СтрЛев |
Левая часть | Строка до указанной позиции |
СтрПрав |
Правая часть | Строка после указанной позиции |
СтрСред |
Средняя часть | Подстрока из центра |
Логика построения результирующей строки заключается в конкатенации (склеивании) левой части (до удаляемого блока) и правой части (после удаляемого блока). Серединка просто отбрасывается.
Текст = "Заказ №123 (Срочный) от 01.01.2026";
Начало = СтрНайти(Текст, "(");
Конец = СтрНайти(Текст, ")");
Если Начало > 0 И Конец > 0 Тогда
ЛеваяЧасть = СтрЛев(Текст, Начало - 1);
ПраваяЧасть = СтрПрав(Текст, СтрДлина(Текст) - Конец);
Текст = ЛеваяЧасть + ПраваяЧасть;
КонецЕсли;
Обратите внимание на смещение индексов. Функция СтрЛев включает символ по указанную позицию, поэтому для исключения самой скобки мы вычитаем единицу. Это частая ошибка новичков.
⚠️ Внимание: Если в строке встречается несколько пар разделителей (например, несколько скобок), описанный выше алгоритм удалит всё от первой открывающей до последней закрывающей. Для точечного удаления нужны циклы или регэкспы.
Использование регулярных выражений для сложных паттернов
Когда структура удаляемого текста непредсказуема или подчиняется сложному шаблону (например, удаление всех цифр, кроме последних четырех, или очистка от спецсимволов), стандартных функций 1С может быть недостаточно.
В этом случае разработчики обращаются к объекту РегулярноеВыражение. Этот инструмент позволяет описать шаблон поиска с помощью мета-символов и удалить все совпадения за одну операцию.
Синтаксис регулярных выражений един для многих языков, но в 1С есть свои особенности вызова. Основной метод для удаления — Заменить, примененный к объекту регулятора.
Текст = "Телефон: +7 (999) 000-00-00 доб. 123";
// Шаблон ищет все, что не является цифрой
РегЭкс = Новый РегулярноеВыражение("[^0-9]");
// Заменяем найденное на пустоту
Результат = РегЭкс.Заменить(Текст, "");
// Результат: "79990000000123"
Использование регулярных выражений значительно упрощает код, делая его короче и читабельнее для сложных задач. Однако за это приходится платить производительностью: компиляция и выполнение регэкспа медленнее, чем нативные функции строки.
Оптимизация регулярных выражений
Если вы используете одно и то же регулярное выражение многократно в цикле, создавайте объект `РегулярноеВыражение` один раз перед циклом, а не внутри него. Это ускорит работу в разы.
Обработка множественных вхождений в цикле
Иногда требуется удалить подстроку не везде, а только определенное количество раз, либо удалять вложенные структуры, которые появляются после первой чистки. В таких случаях необходим цикл.
Циклический перебор позволяет контролировать процесс шаг за шагом. Вы можете искать первое вхождение, удалять его, и повторять поиск в измененной строке до тех пор, пока подстрока не исчезнет полностью или не будет достигнут лимит итераций.
- 🔄 Цикл
Покаудобен для удаления всех вхождений динамически. - 🛑 Цикл
Дляс счетчиком нужен, если нужно удалить ровно N вхождений. - ⚡ Проверка условия выхода из цикла обязательна, чтобы избежать бесконечного зависания.
Примером может служить удаление вложенных комментариев вида / ... / ... / ... /, где простая замена не сработает корректно из-за вложенности.
Пока СтрНайти(Текст, "удалить_это") > 0 Цикл
// Логика удаления первого найденного
Поз = СтрНайти(Текст, "удалить_это");
Текст = СтрЛев(Текст, Поз - 1) + СтрПрав(Текст, СтрДлина(Текст) - Поз - 10); // 10 - длина удаляемого
КонецЦикла;
Такой подход дает полный контроль, но требует аккуратности с индексами. Ошибка в расчете длины сдвига может привести к "поеданию" нужных символов или зацикливанию на одном и том же месте.
Циклическое удаление — самый гибкий, но и самый ресурсоемкий метод. Используйте его только тогда, когда встроенные функции и регулярные выражения не справляются с задачей.
Частые ошибки и производительность операций
При работе со строками в 1С легко допустить ошибки, которые проявятся только на больших объемах данных. Главная проблема — неизменяемость строк. Любая операция изменения создает новый объект в памяти.
Если вы concatenates (склеиваете) строки в цикле тысяч раз, вы создаете тысячи временных объектов, которые затем удаляются сборщиком мусора. Это создает нагрузку на память и процессор.
Для оптимизации в таких случаях следует использовать объект БуферДвоичныхДанных или конструктор строк, если задача позволяет, хотя в типовой 1С чаще обходятся аккуратным планированием операций.
⚠️ Внимание: Никогда не используйте конкатенацию строк внутри цикла, выполняющегося более 1000 раз, без предварительной оценки производительности. Это может замедлить проведение документа с сотнями строк табличной части в десятки раз.
Также стоит учитывать кодировку при работе с внешними системами. Удаление байтов, которые являются частью многобайтового символа (например, эмодзи или иероглифы), может привести к появлению "кракозябр" и нарушению целостности данных.
FAQ: Часто задаваемые вопросы
Как удалить все пробелы из строки в 1С?
Самый простой способ — использовать функцию СтрЗаменить(Строка, " ", ""). Она заменит все символы пробела на пустую строку. Если нужно удалить только лишние пробелы между словами (оставив по одному), потребуется более сложный алгоритм с циклом или регулярное выражение \s+.
Можно ли удалить подстроку без создания новой переменной?
Нет, в языке 1С строки являются неизменяемыми типами данных. Любая операция модификации возвращает новую строку. Вы можете присвоить результат той же переменной, но технически в памяти будет создан новый объект.
Как удалить последний символ строки?
Используйте функцию СтрЛев(Строка, СтрДлина(Строка) - 1). Это вернет всю строку, кроме последнего символа. Обязательно проверьте, что длина строки больше нуля перед выполнением операции.
Что быстрее: СтрЗаменить или РегулярноеВыражение?
Функция СтрЗаменить работает значительно быстрее, так как это нативная оптимизированная операция платформы. Регулярные выражения следует использовать только для сложных паттернов, которые невозможно описать простой подстрокой.
Как удалить спецсимволы из строки для имени файла?
Лучше всего создать строку-константу с запрещенными символами (например, "\/:*?""<>|") и в цикле пройтись по ней, вызывая СтрЗаменить для каждого символа. Либо использовать одно регулярное выражение на все запрещенные символы.