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

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

Как разложить строку на символы в 1С

Как разложить строку на символы в 1С: перебор через Сред(), СтрДлина(), работа с кодами символов, обход по строкам и типичные ошибки при обработке текста.

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

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

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

Базовый способ: цикл со СтрДлина() и Сред()

Универсальный вариант — пройти по строке циклом от первого до последнего символа. Нумерация символов в 1С начинается с единицы, а не с нуля, как во многих других языках. Это важно учитывать, чтобы не пропустить первый символ и не выйти за границу строки.

Функция РазложитьСтрокуНаСимволы(Строка) Экспорт

МассивСимволов = Новый Массив;

ДлинаСтроки = СтрДлина(Строка);

Для Позиция = 1 По ДлинаСтроки Цикл

ТекущийСимвол = Сред(Строка, Позиция, 1);

МассивСимволов.Добавить(ТекущийСимвол);

КонецЦикла;

Возврат МассивСимволов;

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

Функция возвращает массив, где каждый элемент — один символ исходной строки, включая пробелы, знаки препинания и спецсимволы. Если передана пустая строка, СтрДлина() вернёт 0, цикл не выполнится ни разу, и результатом будет пустой массив — это безопасное поведение, дополнительная проверка не обязательна.

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

Порядок действий
  1. 1
    Определите длину строки через СтрДлина(Строка)
  2. 2
    Организуйте цикл Для Позиция = 1 По ДлинаСтроки
  3. 3
    Извлеките символ: Сред(Строка, Позиция, 1)
  4. 4
    Добавьте символ в массив или обработайте его в теле цикла
  5. 5
    Проверьте результат на строке с пробелами и спецсимволами

Обработка символов без промежуточного массива

Если задача — не собрать массив, а проверить или преобразовать строку, промежуточная коллекция не нужна. Символ можно анализировать прямо в теле цикла: подсчитывать цифры, искать недопустимые знаки, собирать новую строку.

Пример — оставить в строке только цифры, отбросив всё остальное. Такой приём типичен при очистке телефонных номеров, ИНН, кодов:

Функция ОставитьТолькоЦифры(Строка) Экспорт

Результат = "";

Для Позиция = 1 По СтрДлина(Строка) Цикл

Символ = Сред(Строка, Позиция, 1);

Если Символ >= "0" И Символ <= "9" Тогда

Результат = Результат + Символ;

КонецЕсли;

КонецЦикла;

Возврат Результат;

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

Сравнение символов строковыми операторами работает, потому что цифры в таблице символов идут подряд. Однако для надёжности при сложных проверках лучше использовать коды символов — об этом ниже.

Анализ символов через КодСимвола()

Функция КодСимвола() возвращает числовой код символа в Unicode, а обратная ей Символ() преобразует код обратно в символ. Это удобно, когда нужно точно определить категорию символа: латиница, кириллица, цифра, управляющий символ.

Для Позиция = 1 По СтрДлина(Строка) Цикл

Символ = Сред(Строка, Позиция, 1);

Код = КодСимвола(Символ);

Если Код >= 48 И Код <= 57 Тогда

// Цифра 0-9

ИначеЕсли Код >= 1040 И Код <= 1103 Тогда

// Русская буква (А-я, без Ё)

ИначеЕсли Код = 32 Тогда

// Пробел

КонецЕсли;

КонецЦикла;

Обратите внимание: буквы «Ё» (код 1025) и «ё» (код 1105) стоят в Unicode отдельно от основного диапазона кириллицы. Если проверка «только русские буквы» должна учитывать Ё, добавьте эти коды явно — иначе валидные данные будут отклонены.

Коды символов также помогают выявить непечатаемые символы: табуляцию (9), перевод строки (10), возврат каретки (13), неразрывный пробел (160). Такие символы часто приходят при копировании данных из Excel или внешних систем и визуально неотличимы от обычных пробелов.

48–57Цифры 0–9

Проверка числовых данных

65–90, 97–122Латинские буквы A–Z, a–z

Выявление латиницы в русском тексте

1040–1103Кириллица А–я (без Ё/ё)

Ё — код 1025, ё — 1105, проверяются отдельно

9, 10, 13, 160Табуляция, ПС, ВК, неразрывный пробел

Невидимые символы из внешних источников

Посимвольный разбор многострочного текста

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

Для НомерСтроки = 1 По СтрЧислоСтрок(Текст) Цикл

СтрокаТекста = СтрПолучитьСтроку(Текст, НомерСтроки);

Для Позиция = 1 По СтрДлина(СтрокаТекста) Цикл

Символ = Сред(СтрокаТекста, Позиция, 1);

// обработка символа

КонецЦикла;

КонецЦикла;

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

Объект Символы содержит именованные константы служебных символов: Символы.ПС (перевод строки), Символы.ВК (возврат каретки), Символы.Таб (табуляция), Символы.НПП (неразрывный пробел). Использование констант читаемее, чем работа с числовыми кодами напрямую.

Когда посимвольный разбор не нужен: альтернативы

Не всякая задача, которая выглядит как «разложить строку», требует посимвольного цикла. Часто нужное решается встроенными функциями быстрее и короче. Перед написанием цикла проверьте, не покрывает ли задачу готовый механизм.

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

Сравнение подходов

Цикл + Сред()

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

СтрРазделить()

Подходит, когда строку нужно разбить по разделителю на части, а не на символы. Не работает для посимвольного анализа

КодСимвола()

Подходит для точной классификации символов по диапазонам Unicode. Избыточен для простого извлечения символов

СтрНайти() / СтрЗаменить()

Подходят для поиска и замены подстрок без разбора всей строки. Не дают доступа к каждому символу

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

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

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

Типичные ошибки
01
Цикл от 0 вместо 1 — в 1С первый символ имеет позицию 1, при старте с нуля Сред() вернёт пустую строку или сместит весь разбор
02
Пропущен третий параметр Сред() — вместо одного символа извлекается весь остаток строки
03
Игнорирование буквы Ё при проверке кириллицы — корректные ФИО и названия отклоняются валидацией
04
Сравнение символов без учёта регистра — 'А' и 'а' считаются разными; при необходимости приводите через ВРег() или НРег()
05
Потеря неразрывных пробелов (код 160) — визуально это пробел, но сравнение с обычным пробелом даёт Ложь, что ломает поиск и сопоставление

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

Контрольные точки

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

Длина результата
Норма

Число элементов массива равно СтрДлина(исходной строки)

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

Элементов меньше или больше — ошибка в границах цикла

Первый и последний символ
Норма

Совпадают с началом и концом исходной строки

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

Сдвиг на одну позицию — цикл начат с 0 или обрезан конец

Спецсимволы
Норма

Пробелы, табуляции, переводы строк присутствуют как отдельные элементы

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

Невидимые символы потеряны или превратились в пустые строки

FAQ

Можно ли обратиться к символу строки по индексу, как в других языках (Строка[0])?

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

Как разложить строку на символы в запросе 1С?

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

Чем отличается СтрРазделить() от посимвольного разбора?

СтрРазделить() режет строку на части по указанному разделителю — например, ФИО на три слова по пробелу. Посимвольный разбор даёт доступ к каждому отдельному знаку. Если указать разделителем пустую строку, функция не разложит строку на символы — для этого нужен цикл.

Как подсчитать, сколько раз конкретный символ встречается в строке?

Пройдите циклом по строке и увеличивайте счётчик при совпадении символа с искомым. Альтернатива без цикла: сравнить СтрДлина(Строка) с длиной строки после СтрЗаменить(Строка, ИскомыйСимвол, "") — разность и есть количество вхождений.

Почему сравнение символа с пробелом не срабатывает, хотя пробел виден?

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

Есть ли ограничение на длину обрабатываемой строки?

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

Итог

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

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