Очистка строк в 1С: пробелы, спецсимволы, регэкспы
Содержание
Убрать пробелы по краям — СокрЛП, выкинуть любой лишний символ — СтрЗаменить, оставить в строке только цифры — цикл по КодСимвола. Это три опорных приёма, которыми в 1С очищают строку от мусора: пробелов, табуляций, переносов, неразрывных пробелов и всего, что приезжает вместе с данными из обмена или буфера обмена.
Чаще всего строку в 1С нужно очистить перед сравнением или поиском: визуально два значения одинаковы, а равенство не срабатывает — виноват невидимый символ на конце. Ниже — рабочие функции под каждую такую задачу, с кодом, который можно скопировать и сразу вставить в модуль.
Какими функциями 1С работает со строками
Весь арсенал очистки строится на горстке встроенных функций. Они есть на любом клиенте и сервере, COM-компоненты не требуются.
| Функция | Что делает |
|---|---|
СокрЛП(Стр) | убирает пробелы слева и справа |
СокрЛ(Стр) / СокрП(Стр) | обрезает пробелы только слева / только справа |
СтрЗаменить(Стр, Что, Чем) | заменяет все вхождения подстроки |
СтрНайти(Стр, Подстрока) | позиция вхождения, 0 если нет |
СтрДлина(Стр) | длина строки |
Сред(Стр, Нач, Длина) | подстрока с позиции |
КодСимвола(Стр, Поз) | код символа в позиции |
Символ(Код) | символ по коду |
СтрНачинаетсяС / СтрЗаканчиваетсяНа | проверка префикса / суффикса |
СокрЛП обрезает только обычные пробелы (код 32) по краям. Табуляцию, перенос строки и неразрывный пробел внутри текста он не трогает — их снимают отдельно через СтрЗаменить.
Для «невидимых» символов удобно системное перечисление Символы:
Символы.ПС // перевод строки, код 10
Символы.ВК // возврат каретки, код 13
Символы.Таб // табуляция, код 9
Символы.НПП // неразрывный пробел, код 160
Как убрать пробелы: по краям, двойные и неразрывные
Начнём с самого частого — лишних пробелов.
Пробелы по краям. Одна функция закрывает задачу:
Результат = СокрЛП(Строка);
Двойные и тройные пробелы внутри сводим к одному. Заменяем два пробела на один, пока в строке остаются сдвоенные:
Пока СтрНайти(Строка, " ") > 0 Цикл
Строка = СтрЗаменить(Строка, " ", " ");
КонецЦикла;
Строка = СокрЛП(Строка);
Цикл нужен именно потому, что СтрЗаменить за один проход превратит четыре пробела подряд в два, а не в один — повторяем, пока сдвоенных не останется.
Все пробелы без исключения (например, из телефона или ИНН) убираем заменой на пустую строку:
Строка = СтрЗаменить(Строка, " ", "");
Неразрывный пробел — тот самый, из-за которого СокрЛП «не работает
». Его часто приносят данные, скопированные с сайтов и из Excel. Код символа — 160, в перечислении это Символы.НПП:
Строка = СтрЗаменить(Строка, Символы.НПП, " ");
Строка = СокрЛП(Строка);
Если после СокрЛП строка всё ещё «с хвостом» — почти всегда это неразрывный пробел или табуляция. Сначала замените их на обычный пробел, потом обрезайте.
Удаляем переносы строк, табуляцию и спецсимволы
Текст из многострочного поля или из выгрузки нередко содержит переносы и табуляцию. Схлопнуть их в один пробел можно пачкой замен:
Строка = СтрЗаменить(Строка, Символы.ПС, " "); // перевод строки
Строка = СтрЗаменить(Строка, Символы.ВК, " "); // возврат каретки
Строка = СтрЗаменить(Строка, Символы.Таб, " "); // табуляция
Строка = СтрЗаменить(Строка, Символы.НПП, " "); // неразрывный пробел
Пока СтрНайти(Строка, " ") > 0 Цикл
Строка = СтрЗаменить(Строка, " ", " ");
КонецЦикла;
Строка = СокрЛП(Строка);
Порядок важен: сначала превращаем все спецсимволы в пробелы, затем схлопываем сдвоенные пробелы и только в конце обрезаем края.
Убрать конкретные символы — те же замены на пустую строку. Например, выкинуть точки, запятые и дефисы из кода:
Для Каждого Симв Из СтрРазделить(".,-/\", "") Цикл
Строка = СтрЗаменить(Строка, Симв, "");
КонецЦикла;
Здесь СтрРазделить(".,-/\", "") с пустым разделителем возвращает массив отдельных символов — удобно перечислить «мусор» в одной строке и пройти по нему циклом.
Как оставить в строке только цифры или только буквы
Для телефонов, ИНН, СНИЛС и артикулов нужен обратный подход: не удалять мусор, а оставить только нужное. Перебираем символы и собираем результат по кодам.
Только цифры (коды 48–57):
Функция ТолькоЦифры(Знач Строка) Экспорт
Результат = "";
Для Позиция = 1 По СтрДлина(Строка) Цикл
Код = КодСимвола(Строка, Позиция);
Если Код >= 48 И Код <= 57 Тогда
Результат = Результат + Символ(Код);
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
Вызов ТолькоЦифры("+7 (900) 123-45-67") вернёт 79001234567.
Только цифры и латинские буквы (для артикулов и серийных номеров) — добавляем диапазоны кодов латиницы (65–90 и 97–122):
Функция ТолькоБуквыИЦифры(Знач Строка) Экспорт
Результат = "";
Для Позиция = 1 По СтрДлина(Строка) Цикл
Код = КодСимвола(Строка, Позиция);
ЭтоЦифра = (Код >= 48 И Код <= 57);
ЭтоЛатБ = (Код >= 65 И Код <= 90) Или (Код >= 97 И Код <= 122);
Если ЭтоЦифра Или ЭтоЛатБ Тогда
Результат = Результат + Символ(Код);
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
Перебор по кодам предсказуем и работает одинаково на Windows и Linux, в тонком и веб-клиенте. Для кириллицы диапазоны кодов шире и зависят от раскладки — если нужны русские буквы, надёжнее проверять символ через поиск в «белом списке» допустимых символов, а не по номерам кодов.
Регулярные выражения: есть ли они в 1С и чем заменить
Встроенного движка регулярных выражений в языке 1С:Предприятия нет. То, что в других языках делается одним Pattern, здесь собирают из СтрЗаменить, СтрНайти и перебора символов — как в примерах выше.
Когда без регэкспа совсем неудобно и база работает на Windows, можно подключить внешний COM-объект движка скриптов:
РегВыр = Новый COMОбъект("VBScript.RegExp");
РегВыр.Global = Истина;
РегВыр.Pattern = "[^0-9]"; // всё, кроме цифр
Результат = РегВыр.Replace(Строка, ""); // удалить
Шаблон [^0-9] означает «любой символ, кроме цифры», а Replace с пустой заменой их вычищает — получается тот же «только цифры», но одной строкой. Для схлопывания любых пробельных символов в один пробел пригодится шаблон \s+:
РегВыр.Pattern = "\s+"; // любые пробелы, табы, переносы подряд
Строка = СокрЛП(РегВыр.Replace(Строка, " "));
COM-объект VBScript.RegExp — это Windows-компонент. На сервере под Linux, в веб-клиенте и в мобильном приложении он недоступен и вызовет ошибку. Если база хоть иногда работает не на Windows, используйте переборные функции из разделов выше, а не регулярные выражения.
Для большинства задач очистки регэксп избыточен: убрать пробелы, переносы и оставить цифры дешевле и переносимее штатными функциями.
Невидимые символы из буфера обмена и выгрузок
Самый коварный мусор — тот, что не видно. Он приезжает, когда значение скопировали из Excel, с сайта, из письма или получили через обмен данными.
Типичные «невидимки»:
- 🔸 неразрывный пробел (код 160) — выглядит как пробел, но
СокрЛПего не берёт; - 🔸 табуляция (код 9) — между «колонками» при копировании из таблицы;
- 🔸 переносы строки и возврат каретки (коды 10 и 13) — в конце многострочных полей;
- 🔸 неразрывный дефис и «длинное тире» — вместо обычного минуса в кодах и артикулах.
Как понять, что в строке невидимый символ: сравните СтрДлина(Строка) до и после СокрЛП. Если длина не изменилась, а «хвост» на вид есть — проверьте код последнего символа:
Если СтрДлина(Строка) > 0 Тогда
Сообщить("Код последнего символа: "
+ КодСимвола(Строка, СтрДлина(Строка)));
КонецЕсли;
Код 160 — неразрывный пробел, 9 — табуляция, 10 или 13 — перенос. Дальше чистите нужной заменой. Эта же проверка объясняет классическую загадку «строки одинаковые, а условие Строка1 = Строка2 ложно»: в одной из них прячется лишний символ.
Снести разом все управляющие символы (коды 0–31: табуляция, переносы, служебные байты из выгрузок) можно одним перебором — оставляем всё, у чего код не ниже 32:
Функция БезУправляющихСимволов(Знач Строка) Экспорт
Результат = "";
Для Позиция = 1 По СтрДлина(Строка) Цикл
Код = КодСимвола(Строка, Позиция);
Если Код >= 32 Тогда
Результат = Результат + Символ(Код);
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
Неразрывный пробел (код 160) эта функция не тронет — он выше порога 32, поэтому его по-прежнему снимают отдельной заменой Символы.НПП.
Готовая функция: универсальный очиститель строки
Собираем всё в одну функцию общего модуля. Она снимает невидимые символы, схлопывает пробелы и обрезает края — то, что нужно перед сравнением, поиском и записью в реквизит:
Функция ОчищеннаяСтрока(Знач Строка) Экспорт
Строка = СтрЗаменить(Строка, Символы.НПП, " ");
Строка = СтрЗаменить(Строка, Символы.Таб, " ");
Строка = СтрЗаменить(Строка, Символы.ПС, " ");
Строка = СтрЗаменить(Строка, Символы.ВК, " ");
Пока СтрНайти(Строка, " ") > 0 Цикл
Строка = СтрЗаменить(Строка, " ", " ");
КонецЦикла;
Возврат СокрЛП(Строка);
КонецФункции
Параметр объявлен через Знач — функция меняет локальную копию и не портит переданную переменную.
Нужно снять в начале лишний префикс (номер, символ №) — пригодится связка СтрНачинаетсяС и Сред:
Если СтрНачинаетсяС(Строка, "№") Тогда
Строка = Сред(Строка, 2); // со второго символа до конца
КонецЕсли;
Три базовые заготовки на каждый день:
- 🔹 очистить от пробелов по краям —
СокрЛП(Строка); - 🔹 свести к одному пробелу и снять невидимки — функция
ОчищеннаяСтрокавыше; - 🔹 оставить только цифры — функция
ТолькоЦифры.
Регистр при очистке и сравнении строк
Отдельная ловушка — регистр. СтрЗаменить и СтрНайти различают большие и маленькие буквы: замена "АБВ" не тронет "абв". Поэтому «ООО Ромашка» и «ооо ромашка» для 1С — разные строки, даже после снятия пробелов.
Перед сравнением регистр приводят к единому. Три функции:
ВРег("ромашка") // РОМАШКА — всё в верхний регистр
НРег("РОМАШКА") // ромашка — всё в нижний
ТРег("ромашка") // Ромашка — первая буква каждого слова заглавная
Надёжный шаблон сравнения двух строк без оглядки на пробелы и регистр — очистить обе функцией ОчищеннаяСтрока, привести к одному регистру и только потом сравнивать:
Функция СтрокиРавны(Знач Строка1, Знач Строка2) Экспорт
Строка1 = ВРег(ОчищеннаяСтрока(Строка1));
Строка2 = ВРег(ОчищеннаяСтрока(Строка2));
Возврат Строка1 = Строка2;
КонецФункции
ВРег и НРег работают и с кириллицей, и с латиницей. Для поиска без учёта регистра приведите к одному регистру и строку, и искомую подстроку: СтрНайти(ВРег(Текст), ВРег(Образец)).
Частые вопросы
Чем `СокрЛП` отличается от `СтрЗаменить(Строка, " ", "")`?
СокрЛП обрезает пробелы только по краям строки, внутренние остаются. СтрЗаменить с пустой заменой убирает все пробелы, включая те, что внутри слов — так чистят телефоны и коды, но не обычный текст.Почему `СокрЛП` не убирает пробел в конце строки?
Символы.НПП и Символы.Таб на обычный пробел, потом применяйте СокрЛП.Есть ли в 1С регулярные выражения из коробки?
VBScript.RegExp, но он не работает на сервере под Linux и в веб-клиенте. Переносимее собирать очистку из СтрЗаменить и перебора по КодСимвола.Как очистить (удалить) строку таблицы значений, а не текст?
ТаблицаЗначений.Удалить(СтрокаТЗ) убирает одну строку, а ТаблицаЗначений.Очистить() — сразу все строки. К очистке текстового значения эти методы отношения не имеют.