При автоматизации загрузки данных из клиент-банков или сторонних систем программисты часто сталкиваются с необходимостью парсинга текстовых полей. Одной из типовых задач является поиск и извлечение расчетного счета (р/с) из строки назначения платежа или комментария. Расчетный счет в РФ всегда состоит из 20 цифр, и его поиск может осложняться наличием других чисел в тексте, лишних пробелов или специфических префиксов.
В этой статье мы подробно разберем несколько способов решения этой задачи: от классических строковых функций до использования регулярных выражений, а также обсудим важные нюансы валидации полученных данных.
Если структура входящей строки относительно стабильна и перед номером счета всегда идет определенный маркер (например, "Р/С" или "р/с"), мы можем использовать наиболее производительный метод — встроенные функции работы со строками. Разберем этот подход на примере.
Проанализируем ситуацию: если мы точно знаем, что счет начинается через несколько символов после подстроки "Р/С", код будет выглядеть следующим образом:
// Исходная строка
Стр = "РАСЧЕТНЫЙ СЧЕТ ИП ВАСИЛИЙ Р/С 40702810100000012345 В ФИЛИАЛЕ БАНКА";
// Ищем позицию вхождения маркера
ПозицияМаркера = СтрНайти(ВРег(Стр), "Р/С");
Если ПозицияМаркера > 0 Тогда
// Вырезаем 20 символов, отступив от начала маркера (длина "Р/С" + пробел)
Результат = Сред(Стр, ПозицияМаркера + 4, 20);
// Дополнительно очистим от возможных случайных пробелов
Результат = СтрЗаменить(Результат, " ", "");
Если СтрДлина(Результат) = 20 Тогда
Сообщить("Счет найден: " + Результат);
КонецЕсли;
КонецЕсли;
Важный момент: использование функции ВРег() позволяет сделать поиск нечувствительным к регистру, что критично при обработке данных из разных банков.
Если маркер "Р/С" отсутствует, но мы знаем, что счет выделен пробелами, мы можем разбить строку на отдельные слова и проверить каждое из них на соответствие критериям (длина 20 символов и отсутствие букв). Рассмотрим подробнее реализацию этого алгоритма:
Функция ИзвлечьСчетИзМассива(НашаСтрока)
// Разделяем строку по пробелам
МассивСлов = СтрРазделить(НашаСтрока, " ", Истина);
Для Каждого Слово Из МассивСлов Цикл
// Удаляем лишние символы, которые могут прилипнуть к счету (точки, запятые)
ЧистоеСлово = СтрЗаменить(Слово, ".", "");
ЧистоеСлово = СтрЗаменить(ЧистоеСлово, ",", "");
// Проверяем длину и что в строке только цифры
Если СтрДлина(ЧистоеСлово) = 20 И ТолькоЦифры(ЧистоеСлово) Тогда
Возврат ЧистоеСлово;
КонецЕсли;
КонецЦикла;
Возврат "";
КонецФункции
Функция ТолькоЦифры(Знач Текст)
Для Поз = 1 По СтрДлина(Текст) Цикл
Символ = Сред(Текст, Поз, 1);
Если Найти("0123456789", Символ) = 0 Тогда
Возврат Ложь;
КонецЕсли;
КонецЦикла;
Возврат Истина;
КонецФункции
Для более сложных случаев, когда счет может быть "склеен" с текстом или находиться в непредсказуемом месте, лучше всего подходят регулярные выражения. До версии платформы 8.3.24 в 1С для этого традиционно использовался объект VBScript.RegExp. Выясним, как составить правильный шаблон.
Шаблон \d{20} означает поиск последовательности ровно из 20 цифр. Однако, чтобы избежать захвата части более длинных чисел, лучше использовать проверку границ слова.
RegExp = Новый COMОбъект("VBScript.RegExp");
RegExp.IgnoreCase = Истина;
RegExp.Global = Истина;
// Шаблон ищет 20 цифр подряд
RegExp.Pattern = "\b\d{20}\b";
Стр = "Текст со счетом 40702810100000012345 внутри предложения";
Matches = RegExp.Execute(Стр);
Если Matches.Count > 0 Тогда
Счет = Matches.Item(0).Value;
Сообщить("Найден счет: " + Счет);
КонецЕсли;
В современных версиях платформы 1С реализована нативная поддержка регулярных выражений. Теперь нам не нужно создавать COMОбъект, что значительно ускоряет работу кода и делает его кроссплатформенным (работает на сервере под Linux). Проанализируем пример использования нового объекта РегулярноеВыражение.
// Создаем объект регулярного выражения
РегВыр = Новый РегулярноеВыражение("\d{20}");
// Ищем все вхождения в строке
Результаты = РегВыр.НайтиВСтроке(ИсходнаяСтрока);
Для Каждого Результат Из Результаты Цикл
НомерСчета = Результат.Значение;
// Здесь можно добавить валидацию контрольного числа
Прервать;
КонецЦикла;
Просто найти 20 цифр недостаточно, так как это может быть номер документа, длинный УИН или технический идентификатор. Настоящий банковский счет имеет контрольный разряд (9-й символ). Для профессионального решения задачи мы рекомендуем выполнять проверку контрольной суммы.
Алгоритм проверки требует наличия БИК банка, в который отправлен платеж. Склеиваются последние три цифры БИК и все 20 цифр счета. Далее применяется весовое умножение каждой цифры на коэффициенты (7, 1, 3). Если итоговая сумма кратна 10, счет является валидным.
Структурные признаки расчетного счета:
Часто пользователи пишут счет с разделителями: 40702.810.1.00000012345 или 40702-810-1-00000012345. Чтобы ваш парсер не пропустил такие случаи, проанализируем стратегию предварительной очистки:
// Оставляем в строке только цифры и пробелы
Для Счетчик = 1 По СтрДлина(Стр) Цикл
Символ = Сред(Стр, Счетчик, 1);
Если Найти("0123456789 ", Символ) = 0 Тогда
Стр = СтрЗаменить(Стр, Символ, " ");
КонецЕсли;
КонецЦикла;
// Теперь можно спокойно применять СтрРазделить или РегулярноеВыражение
Для простых задач и высокой скорости работы выбирайте Метод 1 с функциями СтрНайти и Сред. Если же источник данных "грязный" и счет может быть написан в произвольном формате, оптимальным решением будут регулярные выражения (Метод 4 для новых версий 1С или Метод 3 для старых). Всегда помните, что извлечение строки — это только половина дела, и для критически важных процессов (например, автоматическое создание платежек) обязательна программная проверка контрольного разряда номера счета.