В процессе разработки учетных систем мы часто сталкиваемся с тем, что пользователи вводят номера телефонов в произвольном виде: со скобками, тире, пробелами или начиная с разных префиксов (8, 7, +7). Для корректной работы интеграций с АТС, SMS-шлюзами или для обеспечения уникальности данных в базе, необходимо привести эти записи к единому стандарту. В данной статье мы подробно разберем, как реализовать механизм нормализации телефонных номеров, проанализируем различные подходы и выясним, какие подводные камни могут встретиться при работе с номерами РФ и стран СНГ.
Рассмотрим простейший алгоритм, который часто называют "велосипедом". Его суть заключается в том, чтобы очистить исходную строку от всех символов, кроме цифр, а затем применить логику замены начальных символов. Проанализируем пример кода, предложенный в обсуждении:
ИсхСтр = СокрЛП(НомерТелефона);
РезСтр = "";
Если ИсхСтр <> "" Тогда
Для Инд = 1 По СтрДлина(ИсхСтр) Цикл
Симв = Сред(ИсхСтр, Инд, 1);
Если Найти("0123456789", Симв) = 0 Тогда
Продолжить;
КонецЕсли;
РезСтр = РезСтр + Симв;
КонецЦикла;
Если СтрДлина(РезСтр) = 10 Тогда
РезСтр = "+7" + РезСтр;
КонецЕсли;
Если СтрДлина(РезСтр) = 11 И (Лев(РезСтр, 1) = "8" ИЛИ Лев(РезСтр, 1) = "7") Тогда
РезСтр = "+7" + Сред(РезСтр, 2);
КонецЕсли;
Возврат РезСтр;
КонецЕсли;
Преимущества этого подхода: он максимально прост, не требует внешних библиотек и работает на любой версии платформы 1С. Мы посимвольно проверяем строку с помощью функции Сред и фильтруем мусор через Найти.
Недостатки и риски: такой код не учитывает международную специфику. Например, если пользователь введет номер другой страны, который случайно совпадет по длине (11 цифр) и будет начинаться на "8" (например, номер Японии или Китая), алгоритм ошибочно заменит начало на "+7", чем безвозвратно испортит данные.
Для повышения производительности, особенно при обработке больших массивов данных, разберем более эффективный способ очистки строки с помощью объекта VBScript.RegExp. Это позволит нам избежать медленных циклов Для...По. Проанализируем, как это реализовать:
Функция ОчиститьНомерРегуляркой(Знач ИсходныйНомер)
RegExp = Новый COMОбъект("VBScript.RegExp");
RegExp.Global = Истина;
RegExp.IgnoreCase = Истина;
RegExp.MultiLine = Истина;
// Удаляем все, что не является цифрой
RegExp.Pattern = "[^\d]";
Результат = RegExp.Replace(ИсходныйНомер, "");
Возврат Результат;
КонецФункции
Этот метод работает значительно быстрее стандартного перебора строк. После получения "чистой" последовательности цифр мы можем приступать к форматированию по правилам конкретной страны.
Если вы работаете в современной конфигурации (например, 1С:ERP, 1С:УТ 11 или 1С:Бухгалтерия 3.0), в ней уже интегрирована БСП. Программисту не нужно изобретать способы парсинга, так как в модуле УправлениеКонтактнойИнформациейКлиентСервер предусмотрены профессиональные инструменты.
Выясним, какие функции будут нам полезны:
ОчиститьНомерТелефона(НомерТелефона) — возвращает строку, содержащую только цифры.СформироватьНомерТелефонаДляВывода(СтруктураНомера) — позволяет наложить маску на номер для красивого отображения в интерфейсе или печатных формах.НормализоватьНомерТелефона(НомерТелефона) — пытается привести номер к международному формату E.164.Работа через БСП является приоритетной, так как разработчики фирмы "1С" уже учли большинство исключений и форматов нумерации.
Рассмотрим важный вопрос: всегда ли международный формат в СНГ состоит из 12 символов? Это распространенное заблуждение. Проанализируем структуру номеров разных стран:
Следовательно, жесткая проверка на количество символов "12" в коде — это ошибка. Рекомендуется ориентироваться на стандарт E.164, который допускает длину до 15 цифр и требует наличия знака "+" в начале.
Посмотрим на ситуацию с номерами формата 8-800. Как верно замечено в обсуждении, автоматическая замена первой восьмерки на +7 в таких случаях может быть некорректной. Хотя формат +7800... технически допустим для дозвона, внутри России эти номера традиционно хранятся и воспринимаются именно с "8". Если ваша АТС настроена на распознавание конкретных шаблонов, необдуманная нормализация может нарушить маршрутизацию звонков.
Также важно помнить про добавочные номера. Если в исходной строке есть текст "доб. 123", обычная очистка от нецифровых символов превратит номер в длинную кашу из цифр, где основной номер "склеится" с добавочным. Проанализируем стратегию сохранения таких данных:
// Пример логики разделения основного и добавочного номера
ПозДоб = Найти(НРег(ИсходнаяСтрока), "доб");
Если ПозДоб > 0 Тогда
ОсновнойНомер = Лев(ИсходнаяСтрока, ПозДоб - 1);
Добавочный = Сред(ИсходнаяСтрока, ПозДоб + 3);
// Далее нормализуем ОсновнойНомер отдельно
КонецЕсли;
Подведем итог. Для качественного приведения номеров в порядок в 1С следует придерживаться следующего алгоритма:
+7 (XXX) XXX-XX-XX для глаз пользователя.Соблюдение этих правил позволит создать надежную систему хранения контактной информации, которая не подведет при интеграции с внешними сервисами связи.