Разработка и Конфигурация · 10 мин
Как разложить строку на символы в 1С
Как разложить строку на символы в 1С: перебор через Сред(), СтрДлина(), работа с кодами символов, обход по строкам и типичные ошибки при обработке текста.
Задача разложить строку на отдельные символы возникает в 1С регулярно: при проверке ИНН и контрольных сумм, посимвольной валидации введённых данных, разборе штрихкодов, маскировке части строки или транслитерации. Во встроенном языке 1С нет готовой функции «строка в массив символов», поэтому разложение выполняется вручную — через цикл и функции работы со строками.
Базовый инструментарий прост: функция СтрДлина() возвращает количество символов в строке, а Сред() извлекает подстроку по позиции. Скомбинировав их в цикле, можно получить каждый символ по отдельности и поместить в массив, таблицу значений или сразу обработать. Дополнительно доступны КодСимвола() и Символ() для работы с кодами Unicode.
Ниже разобраны рабочие способы посимвольного разбора: от простейшего цикла до обработки многострочного текста, с проверкой результата, типичными ошибками и ограничениями каждого подхода. Примеры приведены на встроенном языке 1С и подходят для платформы 8.3 как в тонком, так и в толстом клиенте.
Базовый способ: цикл со СтрДлина() и Сред()
Универсальный вариант — пройти по строке циклом от первого до последнего символа. Нумерация символов в 1С начинается с единицы, а не с нуля, как во многих других языках. Это важно учитывать, чтобы не пропустить первый символ и не выйти за границу строки.
Функция РазложитьСтрокуНаСимволы(Строка) Экспорт
МассивСимволов = Новый Массив;
ДлинаСтроки = СтрДлина(Строка);
Для Позиция = 1 По ДлинаСтроки Цикл
ТекущийСимвол = Сред(Строка, Позиция, 1);
МассивСимволов.Добавить(ТекущийСимвол);
КонецЦикла;
Возврат МассивСимволов;
КонецФункции
Функция возвращает массив, где каждый элемент — один символ исходной строки, включая пробелы, знаки препинания и спецсимволы. Если передана пустая строка, СтрДлина() вернёт 0, цикл не выполнится ни разу, и результатом будет пустой массив — это безопасное поведение, дополнительная проверка не обязательна.
Третий параметр Сред() задаёт длину извлекаемой подстроки. Значение 1 даёт ровно один символ. Если его опустить, функция вернёт всё от указанной позиции до конца строки — частая причина неверного результата у начинающих разработчиков.
- 1Определите длину строки через СтрДлина(Строка)
- 2Организуйте цикл Для Позиция = 1 По ДлинаСтроки
- 3Извлеките символ: Сред(Строка, Позиция, 1)
- 4Добавьте символ в массив или обработайте его в теле цикла
- 5Проверьте результат на строке с пробелами и спецсимволами
Обработка символов без промежуточного массива
Если задача — не собрать массив, а проверить или преобразовать строку, промежуточная коллекция не нужна. Символ можно анализировать прямо в теле цикла: подсчитывать цифры, искать недопустимые знаки, собирать новую строку.
Пример — оставить в строке только цифры, отбросив всё остальное. Такой приём типичен при очистке телефонных номеров, ИНН, кодов:
Функция ОставитьТолькоЦифры(Строка) Экспорт
Результат = "";
Для Позиция = 1 По СтрДлина(Строка) Цикл
Символ = Сред(Строка, Позиция, 1);
Если Символ >= "0" И Символ <= "9" Тогда
Результат = Результат + Символ;
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
Сравнение символов строковыми операторами работает, потому что цифры в таблице символов идут подряд. Однако для надёжности при сложных проверках лучше использовать коды символов — об этом ниже.
Анализ символов через КодСимвола()
Функция КодСимвола() возвращает числовой код символа в Unicode, а обратная ей Символ() преобразует код обратно в символ. Это удобно, когда нужно точно определить категорию символа: латиница, кириллица, цифра, управляющий символ.
Для Позиция = 1 По СтрДлина(Строка) Цикл
Символ = Сред(Строка, Позиция, 1);
Код = КодСимвола(Символ);
Если Код >= 48 И Код <= 57 Тогда
// Цифра 0-9
ИначеЕсли Код >= 1040 И Код <= 1103 Тогда
// Русская буква (А-я, без Ё)
ИначеЕсли Код = 32 Тогда
// Пробел
КонецЕсли;
КонецЦикла;
Обратите внимание: буквы «Ё» (код 1025) и «ё» (код 1105) стоят в Unicode отдельно от основного диапазона кириллицы. Если проверка «только русские буквы» должна учитывать Ё, добавьте эти коды явно — иначе валидные данные будут отклонены.
Коды символов также помогают выявить непечатаемые символы: табуляцию (9), перевод строки (10), возврат каретки (13), неразрывный пробел (160). Такие символы часто приходят при копировании данных из Excel или внешних систем и визуально неотличимы от обычных пробелов.
Проверка числовых данных
Выявление латиницы в русском тексте
Ё — код 1025, ё — 1105, проверяются отдельно
Невидимые символы из внешних источников
Посимвольный разбор многострочного текста
Если строка содержит переводы строк, сначала имеет смысл разбить её на отдельные строки через СтрЧислоСтрок() и СтрПолучитьСтроку(), а затем уже раскладывать каждую строку на символы. Это типичный сценарий при разборе многострочных полей, макетов, загруженных текстовых файлов.
Для НомерСтроки = 1 По СтрЧислоСтрок(Текст) Цикл
СтрокаТекста = СтрПолучитьСтроку(Текст, НомерСтроки);
Для Позиция = 1 По СтрДлина(СтрокаТекста) Цикл
Символ = Сред(СтрокаТекста, Позиция, 1);
// обработка символа
КонецЦикла;
КонецЦикла;
Вложенный цикл удобен, когда перевод строки несёт смысл — например, разделяет позиции документа или строки адреса. Если переводы строк не важны, их можно предварительно удалить: СтрЗаменить(Текст, Символы.ПС, "").
Объект Символы содержит именованные константы служебных символов: Символы.ПС (перевод строки), Символы.ВК (возврат каретки), Символы.Таб (табуляция), Символы.НПП (неразрывный пробел). Использование констант читаемее, чем работа с числовыми кодами напрямую.
Когда посимвольный разбор не нужен: альтернативы
Не всякая задача, которая выглядит как «разложить строку», требует посимвольного цикла. Часто нужное решается встроенными функциями быстрее и короче. Перед написанием цикла проверьте, не покрывает ли задачу готовый механизм.
Разбиение строки по разделителю (запятой, точке с запятой) выполняется через СтрРазделить() — она возвращает массив подстрок. Обратная операция — СтрСоединить(). Поиск позиции подстроки делается через СтрНайти(), замена — через СтрЗаменить(), а сложные шаблоны в типовых конфигурациях нередко обрабатывают через общие модули работы со строками.
Сравнение подходов
Подходит для посимвольной проверки, подсчёта, посимвольного преобразования. Ограничение — медленнее встроенных функций на больших строках
Подходит, когда строку нужно разбить по разделителю на части, а не на символы. Не работает для посимвольного анализа
Подходит для точной классификации символов по диапазонам Unicode. Избыточен для простого извлечения символов
Подходят для поиска и замены подстрок без разбора всей строки. Не дают доступа к каждому символу
Проверка результата и типичные ошибки
После реализации разбора проверьте функцию на контрольных примерах: пустая строка, строка из одного символа, строка с пробелами по краям, строка с кириллицей и латиницей вперемешку, строка с неразрывными пробелами и переводами строк. Такой набор покрывает большинство скрытых дефектов.
Быстрый способ убедиться в корректности — вывести результат через Сообщить() с указанием позиции и кода каждого символа. Если количество элементов массива равно СтрДлина() исходной строки, а символы совпадают по позициям, разбор выполнен правильно.
Отдельный риск — модификация исходной строки внутри цикла разбора. Если вы меняете переменную, по которой идёт цикл, длина, вычисленная до цикла, перестанёт соответствовать реальности. Собирайте результат в новую переменную, а исходную строку оставляйте неизменной.
Как проверить результат
Число элементов массива равно СтрДлина(исходной строки)
Элементов меньше или больше — ошибка в границах цикла
Совпадают с началом и концом исходной строки
Сдвиг на одну позицию — цикл начат с 0 или обрезан конец
Пробелы, табуляции, переводы строк присутствуют как отдельные элементы
Невидимые символы потеряны или превратились в пустые строки
FAQ
Можно ли обратиться к символу строки по индексу, как в других языках (Строка[0])?
Нет, встроенный язык 1С не поддерживает индексацию строк. Единственный способ получить символ по позиции — функция Сред(Строка, Позиция, 1) или Лев()/Прав() для крайних символов.
Как разложить строку на символы в запросе 1С?
Язык запросов не имеет функций посимвольного разбора. Если такая обработка нужна, строку извлекают запросом, а разбор выполняют уже во встроенном языке циклом со Сред(). Для поиска по шаблону в запросе используйте оператор ПОДОБНО.
Чем отличается СтрРазделить() от посимвольного разбора?
СтрРазделить() режет строку на части по указанному разделителю — например, ФИО на три слова по пробелу. Посимвольный разбор даёт доступ к каждому отдельному знаку. Если указать разделителем пустую строку, функция не разложит строку на символы — для этого нужен цикл.
Как подсчитать, сколько раз конкретный символ встречается в строке?
Пройдите циклом по строке и увеличивайте счётчик при совпадении символа с искомым. Альтернатива без цикла: сравнить СтрДлина(Строка) с длиной строки после СтрЗаменить(Строка, ИскомыйСимвол, "") — разность и есть количество вхождений.
Почему сравнение символа с пробелом не срабатывает, хотя пробел виден?
Скорее всего, в строке неразрывный пробел (код 160) или табуляция, которые визуально похожи на обычный пробел (код 32). Проверьте символ через КодСимвола() и при необходимости замените Символы.НПП на обычный пробел до начала разбора.
Есть ли ограничение на длину обрабатываемой строки?
Строки в 1С не ограничены фиксированной длиной, но посимвольный цикл на очень больших текстах выполняется заметно дольше встроенных функций. Для строк в сотни тысяч символов по возможности заменяйте разбор на СтрНайти(), СтрЗаменить() или СтрРазделить().
Что важно запомнить
Строка в 1С раскладывается на символы циклом от 1 до СтрДлина() с извлечением каждого символа через Сред(Строка, Позиция, 1). Для классификации символов используйте КодСимвола(), для служебных символов — объект Символы. Перед написанием цикла проверьте, не решает ли задачу СтрРазделить(), СтрНайти() или СтрЗаменить().