Разработка и Конфигурация · 8 мин
1С: как найти пробел в строке
Как найти пробел в строке в 1С: функции Найти() и СтрНайти(), проверка наличия, позиция последнего пробела, разбор на части, типичные ошибки и примеры кода.
Поиск пробела в строке — одна из самых частых задач при разработке на встроенном языке 1С. Она возникает при разборе ФИО на фамилию, имя и отчество, при обработке адресов, при очистке данных, загруженных из Excel или внешних систем, и при валидации пользовательского ввода. Встроенный язык платформы предоставляет несколько инструментов для этого, и выбор зависит от версии платформы и конкретной задачи.
Базовый инструмент — функция Найти(), доступная во всех версиях платформы. Начиная с версии 8.3.6 добавлен семейство строковых функций СтрНайти(), СтрЗаменить(), СтрРазделить(), которые работают более предсказуемо и поддерживают направление поиска. Ниже разобраны оба подхода, сценарии их применения и типичные ошибки.
Функция Найти(): базовый способ поиска пробела
Функция Найти(Строка, ПодстрокаПоиска) возвращает номер позиции первого вхождения подстроки в строку. Нумерация символов начинается с 1. Если пробел не найден, функция возвращает 0 — это ключевой признак, который используется для проверки наличия пробела.
Пример простейшего поиска:
Строка = "Иванов Иван";
Позиция = Найти(Строка, " ");
Если Позиция > 0 Тогда
Сообщить("Пробел найден на позиции " + Позиция);
Иначе
Сообщить("Пробелов нет");
КонецЕсли;
В данном примере функция вернёт 7 — позицию пробела между фамилией и именем. Функция находит только первое вхождение: если в строке несколько пробелов, остальные нужно искать отдельно.
Функция СтрНайти(): современный вариант с расширенными параметрами
Начиная с платформы 8.3.6 доступна функция СтрНайти() с более гибким синтаксисом. Она позволяет указать направление поиска, начальную позицию и номер вхождения, что избавляет от ручных циклов во многих задачах.
Синтаксис: СтрНайти(Строка, ПодстрокаПоиска, НаправлениеПоиска, НачальнаяПозиция, НомерВхождения). Два первых параметра обязательны, остальные опциональны.
Строка = "Иванов Иван Иванович";
// Первый пробел
Поз1 = СтрНайти(Строка, " "); // 7
// Второй пробел
Поз2 = СтрНайти(Строка, " ", , , 2); // 12
// Последний пробел — поиск с конца
ПозПосл = СтрНайти(Строка, " ", НаправлениеПоиска.СКонца);
Направление НаправлениеПоиска.СКонца особенно полезно, когда нужно отделить последнее слово в строке — например, выделить отчество из полного ФИО или расширение из имени файла. Без этой функции пришлось бы перебирать строку в цикле от последнего символа к первому.
Как выбрать функцию
Проверка наличия пробела в строке
Часто позиция пробела не нужна — требуется лишь узнать, есть он или нет. Например, при проверке, что пользователь ввёл логин без пробелов, или что артикул не содержит лишних символов. Для этого достаточно сравнить результат Найти() с нулём.
Если Найти(Логин, " ") > 0 Тогда
ВызватьИсключение "Логин не должен содержать пробелы";
КонецЕсли;
Отдельный случай — проверка на пробелы в начале и конце строки. Для этого удобнее сравнить строку с результатом функции СокрЛП(): если они не равны, значит, по краям есть пробелы или другие незначащие символы (табуляция, перевод строки).
Если Строка <> СокрЛП(Строка) Тогда
Сообщить("Есть пробелы в начале или в конце строки");
КонецЕсли;
Поиск всех пробелов и разбор строки на части
Когда нужно найти каждый пробел — например, чтобы разбить ФИО на три части — есть два подхода: цикл с поиском от текущей позиции или готовая функция СтрРазделить().
Классический цикл с Найти() требует обрезки строки после каждого найденного пробела и накопления смещения. Это громоздко и легко приводит к ошибкам в индексах. С СтрРазделить() задача решается одной строкой:
Части = СтрРазделить("Иванов Иван Иванович", " ");
Фамилия = Части[0]; // "Иванов"
Имя = Части[1]; // "Иван"
Отчество = Части[2]; // "Иванович"
Функция возвращает массив подстрок. По умолчанию пустые части (при двойных пробелах) включаются в результат — если они не нужны, передайте вторым параметром Ложь: СтрРазделить(Строка, " ", Ложь). Это важно при обработке «грязных» данных из внешних источников, где между словами может стоять несколько пробелов.
- 1Очистите строку: Строка = СокрЛП(Строка)
- 2Разбейте: Части = СтрРазделить(Строка, " ", Ложь)
- 3Проверьте количество элементов: Части.Количество() должно быть не меньше ожидаемого
- 4Извлеките элементы по индексам: Части[0], Части[1], Части[2]
- 5Обработайте случаи, когда частей меньше трёх — не обращайтесь к несуществующим индексам
Неразрывный пробел и другие невидимые символы
Частая причина «неработающего» поиска — в строке стоит не обычный пробел (код 32), а неразрывный пробел (код 160). Такие символы регулярно попадают в данные при копировании из веб-страниц, Word или при выгрузках из других систем. Визуально они неотличимы, но Найти(Строка, " ") их не находит.
Для поиска неразрывного пробела используйте функцию Символ():
НПП = Символ(160); // неразрывный пробел
Позиция = Найти(Строка, НПП);
Надёжная практика — перед разбором строки заменить все неразрывные пробелы на обычные: Строка = СтрЗаменить(Строка, Символ(160), " "). Аналогично могут встречаться табуляция (Символы.Таб) и символы перевода строки (Символы.ПС, Символы.ВК) — для них действует тот же приём.
Практические приёмы и ограничения
Несколько полезных приёмов, которые часто используются вместе с поиском пробела. Подсчёт количества пробелов в строке без цикла: СтрЧислоВхождений(Строка, " ") — функция доступна с платформы 8.3.6. Извлечение первого слова: Лев(Строка, Найти(Строка, " ") - 1), но только после проверки, что пробел вообще есть, иначе получите строку нулевой длины или ошибку логики.
Извлечение текста после последнего пробела удобно делать через СтрНайти() с поиском с конца:
Поз = СтрНайти(Строка, " ", НаправлениеПоиска.СКонца);
Если Поз > 0 Тогда
ПоследнееСлово = Сред(Строка, Поз + 1);
КонецЕсли;
Ограничение, о котором стоит помнить: строковые функции 1С не поддерживают регулярные выражения. Если нужно искать «любой пробельный символ» или сложный шаблон, придётся либо перебирать символы в цикле с проверкой кодов, либо использовать внешние компоненты. Для большинства учётных задач достаточно предварительной нормализации строки через СтрЗаменить().
Что важно запомнить
Найти(Строка, " ") возвращает позицию первого пробела или 0. СтрНайти() добавляет поиск с конца и по номеру вхождения, СтрРазделить() разбивает строку по всем пробелам сразу. Перед разбором нормализуйте строку: замените неразрывные пробелы и примените СокрЛП().
Частые вопросы
Что возвращает Найти(), если пробела в строке нет?
Функция возвращает число 0. Поэтому проверка наличия пробела выглядит как Найти(Строка, " ") > 0. Сравнивать результат с Неопределено или пустой строкой нельзя — такая проверка всегда будет ложной.
Как найти последний пробел в строке?
Используйте СтрНайти(Строка, " ", НаправлениеПоиска.СКонца) на платформе 8.3.6 и новее. На старых версиях придётся перебирать символы в цикле от конца строки к началу и сравнивать каждый с пробелом.
Почему Найти() не находит пробел, хотя он виден на экране?
Скорее всего, в строке неразрывный пробел (код символа 160) или табуляция. Перед поиском выполните Строка = СтрЗаменить(Строка, Символ(160), " ") — это приведёт невидимые разделители к обычному пробелу.
Как посчитать количество пробелов в строке?
На платформе 8.3.6+ используйте СтрЧислоВхождений(Строка, " "). Альтернатива для старых версий — вычислить разность длин исходной строки и строки после СтрЗаменить(Строка, " ", ""), либо взять СтрРазделить(Строка, " ").Количество() минус 1.
Чем СтрНайти() лучше Найти()?
СтрНайти() поддерживает направление поиска (с начала или с конца), начальную позицию и номер вхождения, что убирает необходимость в ручных циклах. Найти() остаётся актуальной только для совместимости со старыми версиями платформы.
Как проверить, что строка состоит только из пробелов?
Примените СокрЛП(Строка) и сравните результат с пустой строкой: Если СокрЛП(Строка) = "" Тогда. Функция удалит все пробельные символы по краям, и если ничего не осталось — значит, содержательных данных в строке нет.