К статье
Практический материал

Разработка и Конфигурация · 12 мин

1С: как заменить символ в строке

Как заменить символ или подстроку в строке 1С: функция СтрЗаменить, работа с пробелами, переносами и спецсимволами, примеры кода и типичные ошибки.

Замена символов в строке — одна из самых частых задач при разработке и доработке конфигураций 1С: очистка номеров документов от пробелов, замена разделителей в выгрузках, нормализация данных при обмене, подготовка строк для поиска. Во встроенном языке 1С для этого есть штатная функция СтрЗаменить(), которая в простых сценариях решает задачу одной строкой кода.

Однако у функции есть особенности: она заменяет все вхождения подстроки сразу, не работает с регулярными выражениями и чувствительна к регистру. Для части задач — например, замены только первого вхождения или удаления непечатаемых символов — нужны дополнительные приёмы: комбинация СтрНайти() и Лев()/Сред(), перебор символов, работа с кодами символов через Символ() и КодСимвола().

Ниже разобраны основные способы замены символов в строке 1С: от простого вызова СтрЗаменить() до обработки спецсимволов и массовой замены по таблице соответствий, а также типичные ошибки и способы проверки результата.

Функция СтрЗаменить: синтаксис и базовое использование

Функция СтрЗаменить() принимает три параметра: исходную строку, подстроку поиска и подстроку замены. Возвращаемое значение — новая строка, в которой все вхождения подстроки поиска заменены на подстроку замены. Исходная строка не изменяется, результат нужно присваивать переменной.

ИсходнаяСтрока = "Номер: 000-000-123";

Результат = СтрЗаменить(ИсходнаяСтрока, "-", "/");

// Результат: "Номер: 000/000/123"

Важно понимать, что функция заменяет все вхождения, а не только первое. Если нужно заменить дефис только в начале номера, а остальные оставить, СтрЗаменить() в чистом виде не подойдёт — потребуется приём с поиском позиции, описанный ниже.

Замена работает и с подстроками произвольной длины: можно заменить слово, фразу или целый фрагмент. Например, СтрЗаменить(Строка, "руб.", "RUB") заменит все вхождения сокращения валюты. Пустая строка в третьем параметре означает удаление: СтрЗаменить(Строка, " ", "") уберёт все пробелы.

Замена одного символа и спецсимволов

Замена одиночного печатного символа — частный случай: СтрЗаменить(Строка, ";", ",") заменит все точки с запятой на запятые. Сложнее обстоит дело с непечатаемыми символами: переносом строки, табуляцией, неразрывным пробелом, которые часто попадают в данные при копировании из Excel, Word или веб-страниц.

Для таких символов используется функция Символ(Код), возвращающая символ по его коду. Типичные коды: 9 — табуляция, 10 — перевод строки (LF), 13 — возврат каретки (CR), 160 — неразрывный пробел. Встроенная константа Символы.ПС и Символы.Таб даёт те же значения без запоминания кодов.

// Удаление неразрывных пробелов из строки с числом

СтрокаСуммы = СтрЗаменить(СтрокаСуммы, Символ(160), "");

// Замена переносов строк на пробел

Текст = СтрЗаменить(Текст, Символы.ПС, " ");

Текст = СтрЗаменить(Текст, Символ(13), "");

Неразрывный пробел (код 160) — частый источник проблем: визуально он неотличим от обычного пробела, но СтрЗаменить(Строка, " ", "") его не удалит. Если строка с числом «не преобразуется» в число или сравнение строк даёт ложный результат, первым делом проверьте наличие символа 160.

1c
Строка = СтрЗаменить(Строка, Символ(160), " "); // неразрывный пробел -> обычный
Строка = СтрЗаменить(Строка, Символы.Таб, " ");      // табуляция -> пробел
Строка = СокрЛП(Строка);                                // убрать краевые пробелы

Как заменить только первое вхождение или символ в конкретной позиции

Стандартной функции «заменить первое вхождение» во встроенном языке нет, поэтому задача решается комбинацией СтрНайти(), Лев() и Сред(): находим позицию подстроки, отрезаем часть до неё и после неё, вставляем замену между ними.

Функция ЗаменитьПервое(Строка, ЧтоИскать, ЧемЗаменить)

Позиция = СтрНайти(Строка, ЧтоИскать);

Если Позиция = 0 Тогда

Возврат Строка; // вхождения нет, возвращаем как есть

КонецЕсли;

Возврат Лев(Строка, Позиция - 1) + ЧемЗаменить

+ Сред(Строка, Позиция + СтрДлина(ЧтоИскать));

КонецФункции

Тот же приём работает для замены символа по известной позиции: Лев(Строка, Позиция - 1) + НовыйСимвол + Сред(Строка, Позиция + 1). Это полезно, когда формат строки фиксирован — например, нужно заменить разделитель на строго определённом месте в номере или коде.

При написании таких функций обязательно обрабатывайте случай Позиция = 0 (подстрока не найдена). Иначе Лев() с отрицательной длиной и Сред() со сдвинутой позицией дадут непредсказуемый результат или ошибку исполнения.

Порядок действий при замене первого вхождения
  1. 1
    Найдите позицию подстроки через СтрНайти(Строка, Подстрока)
  2. 2
    Проверьте, что позиция больше нуля — иначе заменять нечего
  3. 3
    Соберите результат: Лев(Строка, Позиция-1) + Замена + Сред(Строка, Позиция + СтрДлина(Подстрока))
  4. 4
    Проверьте результат на контрольном примере с несколькими вхождениями

Массовая замена по таблице соответствий

Когда нужно заменить сразу несколько разных символов — например, транслитерация, очистка строки от недопустимых в имени файла знаков, нормализация телефонных номеров — удобно последовательно применить СтрЗаменить() для каждой пары «что искать — чем заменить», хранящейся в соответствии или таблице значений.

Соответствие = Новый Соответствие;

Соответствие.Вставить("\", "_");

Соответствие.Вставить("/", "_");

Соответствие.Вставить(":", "_");

Соответствие.Вставить("?", "");

Для Каждого Пара Из Соответствие Цикл

ИмяФайла = СтрЗаменить(ИмяФайла, Пара.Ключ, Пара.Значение);

КонецЦикла;

Здесь есть тонкость: замены выполняются последовательно, и результат одной замены может стать входом для следующей. Если в таблице есть цепочки вида «а → б» и «б → в», итог будет отличаться от ожидаемого. В таких случаях либо меняйте порядок обхода, либо заменяйте через промежуточный маркер, которого точно нет в данных.

Альтернатива — посимвольный перебор строки с проверкой каждого символа: подходит, когда нужно оставить только допустимые символы (например, только цифры). Цикл по СтрДлина(Строка) с Сред(Строка, Н, 1) и проверкой «символ в списке разрешённых» надёжнее, чем длинная цепочка замен «плохих» символов, которых может быть непредсказуемо много.

Сравнение подходов к замене

СтрЗаменить

Быстро и просто, заменяет все вхождения; не подходит для замены по позиции и шаблону

СтрНайти + Лев + Сред

Полный контроль: первое вхождение, конкретная позиция; больше кода и ручных проверок

Посимвольный перебор

Гибкая фильтрация по списку допустимых символов; медленнее на очень длинных строках

Регулярные выражения (VBScript.RegExp)

Мощный поиск по шаблону; работает только на Windows-клиенте, недоступно на сервере Linux и в мобильной платформе

Регулярные выражения и их ограничения в 1С

Во встроенном языке 1С нет нативной поддержки регулярных выражений. На платформе под Windows традиционно используют COM-объект VBScript.RegExp, который позволяет искать и заменять по шаблону — например, удалить все нецифровые символы одним выражением [^0-9].

RegExp = Новый COMОбъект("VBScript.RegExp");

RegExp.Pattern = "[^0-9]";

RegExp.Global = Истина;

ТолькоЦифры = RegExp.Replace(ИсходнаяСтрока, "");

У этого подхода жёсткое ограничение: COM-объекты доступны только в Windows-окружении. На Linux-сервере, в веб-клиенте и мобильной платформе код завершится ошибкой. Если решение должно работать кроссплатформенно, регулярные выражения через COM применять нельзя — используйте посимвольный перебор или цепочки СтрЗаменить().

Ещё один риск — падение производительности при массовом создании COM-объекта в цикле. Если замена выполняется для тысяч строк, создавайте объект RegExp один раз до цикла и переиспользуйте его, меняя только входную строку.

Проверка результата и типичные ошибки

После замены результат стоит проверить хотя бы на контрольных примерах: строка без искомого символа, строка из одних искомых символов, пустая строка, строка с символом в начале и в конце. Эти граничные случаи чаще всего выявляют ошибки в собственных функциях замены.

Для отладки удобно выводить длину строки до и после замены и использовать СтрЧислоВхождений(), чтобы убедиться, что заменено ожидаемое количество вхождений. Если после замены неразрывных пробелов строка «не изменилась», проверьте коды символов через КодСимвола() — возможно, в данных другой служебный символ.

Отдельный класс проблем — замены в данных, которые затем уходят в запросы или имена файлов. Строка, очищенная от одних символов, может содержать другие, недопустимые в конкретном контексте. Проверяйте результат именно в целевом сценарии: открытие файла, выполнение запроса, передача во внешнюю систему.

Типичные ошибки
01
Вызов СтрЗаменить() без присваивания результата — строка остаётся прежней
02
Попытка удалить неразрывный пробел обычным пробелом — символ 160 не совпадает с символом 32
03
Ожидание, что заменится только первое вхождение — СтрЗаменить заменяет все
04
Отсутствие проверки Позиция = 0 при замене через СтрНайти — ошибка или искажение строки
05
Использование VBScript.RegExp на сервере Linux — ошибка исполнения в рабочей базе
06
Последовательные замены, где результат одной совпадает с образцом другой — двойная замена и неверный итог
Контрольные точки

Как проверить результат

Количество замен
Норма

СтрЧислоВхождений до замены равно ожидаемому числу изменений

Тревожный признак

Замен произошло больше или меньше, чем вхождений

Невидимые символы
Норма

После очистки КодСимвола() показывает только ожидаемые коды

Тревожный признак

Остаются коды 160, 9, 13 в середине строки

Граничные случаи
Норма

Пустая строка и строка без искомого символа возвращаются без изменений

Тревожный признак

Ошибка исполнения или искажённый результат

Целевое использование
Норма

Строка принимается файлом, запросом или внешней системой

Тревожный признак

Ошибка формата на этапе использования

Частые вопросы

Как заменить символ в строке только в определённой позиции?

Соберите новую строку из частей: Лев(Строка, Позиция - 1) + НовыйСимвол + Сред(Строка, Позиция + 1). Предварительно убедитесь, что позиция находится в диапазоне от 1 до длины строки, иначе получите ошибку или неверный результат.

Почему СтрЗаменить не удаляет пробелы в строке с числом?

Скорее всего, в строке неразрывные пробелы (код 160), которые визуально неотличимы от обычных. Используйте СтрЗаменить(Строка, Символ(160), ""). Проверить фактические коды символов можно функцией КодСимвола() в цикле по строке.

Можно ли заменить символ без учёта регистра?

СтрЗаменить() чувствительна к регистру. Обходной путь — выполнить замену для обоих вариантов: СтрЗаменить(СтрЗаменить(Строка, "А", "X"), "а", "X"). Для сложных случаев с множеством букв проще привести копию строки к одному регистру через НРег() или ВРег(), но помните, что это изменит и остальные символы.

Как удалить из строки все символы, кроме цифр?

Кроссплатформенный способ — посимвольный перебор: пройдите циклом по строке, проверяйте каждый символ через СтрНайти("0123456789", Символ) > 0 и складывайте подходящие в результат. Вариант с VBScript.RegExp короче, но работает только на Windows.

Заменяет ли СтрЗаменить только первое вхождение?

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

Что быстрее: цепочка СтрЗаменить или посимвольный перебор?

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

Итог

Что важно запомнить

Основной инструмент замены символов в 1С — СтрЗаменить(): она заменяет все вхождения и возвращает новую строку. Для первого вхождения и замены по позиции комбинируйте СтрНайти(), Лев() и Сред(). Непечатаемые символы заменяйте через Символ(код) и Символы.ПС, а COM-регулярные выражения применяйте только в Windows-окружении.