В практике разработки на платформе 1С:Предприятие часто возникает задача очистки данных, введенных пользователем. Типичный пример — номер телефона или очистка штрихкодов от нечисловых символов. В интерфейсе мы часто используем маски вроде +9(999)999-99-99 для удобства ввода, однако для интеграции с АТС, отправки SMS или выгрузки в другие системы требуется "чистая" строка, состоящая только из цифр. Рассмотрим подробнее, как решить эту задачу различными методами, проанализируем их плюсы и минусы, а также разберем вопросы производительности.
Это самый надежный и универсальный способ, который будет работать на любой версии платформы и любой операционной системе (Windows или Linux). Проанализируем логику: мы проходим по каждому символу входящей строки, проверяем, является ли он цифрой, и если да — добавляем его в результирующую строку.
Разберем пример реализации в виде функции:
Функция ОставитьТолькоЦифры(ВхСтрока)
ВыхСтрока = "";
Для Позиция = 1 По СтрДлина(ВхСтрока) Цикл
Символ = Сред(ВхСтрока, Позиция, 1);
Если Символ >= "0" И Символ <= "9" Тогда
ВыхСтрока = ВыхСтрока + Символ;
КонецЕсли;
КонецЦикла;
Возврат ВыхСтрока;
КонецФункции
Преимущества данного подхода:
Однако у этого метода есть и недостаток. При обработке очень длинных строк (тысячи символов) конкатенация строк в 1С (операция +) может работать медленно из-за особенностей выделения памяти. Для коротких строк типа номера телефона это не критично.
Если ваша база работает на ОС Windows, можно воспользоваться объектом VBScript.RegExp. Это мощный инструмент, который позволяет заменить все нецифровые символы одной строчкой кода. Посмотрим на пример, предложенный в обсуждении:
RegExp = Новый COMОбъект("VBScript.RegExp");
RegExp.IgnoreCase = Истина;
RegExp.Global = Истина;
RegExp.MultiLine = Истина;
RegExp.Pattern = "[^0-9]"; // Шаблон: искать всё, что НЕ является цифрой
ТелефонИсправленный = RegExp.Replace(Телефон, "");
Выясним причину популярности этого метода: он крайне лаконичен. Шаблон [^0-9] (или [^\d]) мгновенно находит все лишние знаки (пробелы, скобки, плюсы) и удаляет их.
Важное примечание: Начиная с версии платформы 8.3.24, в 1С появились встроенные регулярные выражения. Теперь не нужно создавать COMОбъект, что делает код стабильным на Linux-серверах:
РегВыр = Новый РегулярноеВыражение("[^0-9]");
Результат = РегВыр.Заменить(ИсходныйНомер, "");
Если вы работаете в современной конфигурации (например, УТ 11, БП 3.0 или ERP), скорее всего, в ней уже установлена БСП. В этом случае изобретать велосипед не нужно — разработчики 1С уже написали оптимизированные функции. Рассмотрим использование общего модуля СтроковыеФункцииКлиентСервер.
Вы можете вызвать готовую функцию:
// В типовых конфигурациях часто встречается такой метод:
ЧистыйНомер = СтроковыеФункцииКлиентСервер.ТолькоЦифрыВСтроке(Телефон);
Или специализированный метод для контактной информации:
ЧистыйНомер = УправлениеКонтактнойИнформациейКлиентСервер.ОставитьТолькоЦифрыВСтроке(Телефон);
Преимущество этого метода в том, что он проверен на тысячах внедрений и учитывает нюансы производительности платформы.
Рассмотрим оригинальный способ, который появился в платформе с выходом версии 8.3.8. Он позволяет обойтись без циклов и регулярных выражений, используя массив как промежуточное хранилище.
// Определяем все возможные разделители (лишние символы)
Разделители = " +()-";
МассивЧастей = СтрРазделить(Телефон, Разделители, Ложь);
ЧистыйНомер = СтрСоединить(МассивЧастей, "");
Проанализируем ситуацию: этот метод хорош, если вы точно знаете набор лишних символов. Однако, если в строке окажутся буквы или другие знаки, не включенные в переменную Разделители, они останутся в итоговой строке. Поэтому для полной очистки лучше использовать методы 1 или 2.
Иногда задача стоит шире: оставить не только цифры, но, например, цифры и символ "+". Для этого удобно использовать функцию с параметром допустимых символов:
Функция ОчиститьСтрокуПоДопустимым(Знач ИсходнаяСтрока, ДопустимыеСимволы)
Результат = "";
Для Индекс = 1 По СтрДлина(ИсходнаяСтрока) Цикл
Символ = Сред(ИсходнаяСтрока, Индекс, 1);
Если СтрНайти(ДопустимыеСимволы, Символ) > 0 Тогда
Результат = Результат + Символ;
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
// Пример вызова:
НужныйФормат = ОчиститьСтрокуПоДопустимым(Телефон, "0123456789+");
Если вам нужно обработать массив из 100 000 строк, использование прямого сложения строк (Строка = Строка + Символ) может существенно замедлить процесс. В 1С строки неизменяемы: при каждом добавлении символа система создает в памяти новую строку. Выясним, как сделать это быстрее.
Правильный подход при больших объемах — использование массива:
Функция ОставитьТолькоЦифрыБыстро(ВхСтрока)
МассивСимволов = Новый Массив;
Для Позиция = 1 По СтрДлина(ВхСтрока) Цикл
Символ = Сред(ВхСтрока, Позиция, 1);
Если Символ >= "0" И Символ <= "9" Тогда
МассивСимволов.Добавить(Символ);
КонецЕсли;
КонецЦикла;
Возврат СтрСоединить(МассивСимволов, "");
КонецФункции
Использование СтрСоединить работает значительно быстрее на больших текстах, так как выделение памяти происходит один раз для всего результирующего массива.
Часто после удаления символов мы получаем номер, начинающийся на "8" (внутренний российский стандарт). Для работы многих сервисов требуется международный формат, начинающийся на "7". Посмотрим, как это реализовать:
Номер = ОставитьТолькоЦифры(ИсходныйТелефон);
Если СтрДлина(Номер) = 11 И Лев(Номер, 1) = "8" Тогда
Номер = "7" + Сред(Номер, 2);
ИначеЕсли СтрДлина(Номер) = 10 Тогда
Номер = "7" + Номер;
КонецЕсли;
Подведем итог: для разовых задач в обычных формах (1С 8.2) проще всего использовать цикл по символам. В современных конфигурациях на платформе 8.3 следует отдавать предпочтение встроенным функциям БСП или новому объекту РегулярноеВыражение. Это обеспечит чистоту вашего кода и его стабильную работу в любых условиях.