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

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

Как найти последний пробел в строке в 1С

Как найти позицию последнего пробела в строке 1С с помощью СтрНайти и направления СКонца, отделить фамилию от имени, обработать случаи, когда пробела нет.

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

Главная тонкость в том, что по умолчанию СтрНайти ищет с начала строки и возвращает первое вхождение. Чтобы получить именно последний пробел, используется параметр направления поиска со значением СКонца. Ниже разобран синтаксис, готовые функции, обработка крайних случаев и альтернативные подходы для старых версий платформы.

Функция СтрНайти с направлением поиска СКонца

Начиная с платформы 8.3.6 функция СтрНайти поддерживает третий параметр — направление поиска. Полный синтаксис выглядит так: СтрНайти(Строка, ПодстрокаПоиска, НаправлениеПоиска, НачальнаяПозиция, НомерВхождения). Для поиска последнего пробела достаточно первых трёх аргументов.

Пример кода:

Строка = "Иванов Иван Иванович";

Позиция = СтрНайти(Строка, " ", НаправлениеПоиска.СКонца);

// Позиция = 13 — последний пробел перед "Иванович"

Функция возвращает номер символа, начиная с единицы, как и все строковые функции встроенного языка 1С. Если искомой подстроки нет, результат равен нулю — это важно учитывать перед тем, как резать строку функциями Лев, Прав или Сред.

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

bsl
Позиция = СтрНайти(СтрокаПоиска, " ", НаправлениеПоиска.СКонца);

Как отрезать часть строки после последнего пробела

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

Строка = "Иванов Иван Иванович";

Позиция = СтрНайти(Строка, " ", НаправлениеПоиска.СКонца);

Если Позиция > 0 Тогда

ЛеваяЧасть = Лев(Строка, Позиция - 1); // "Иванов Иван"

ПраваяЧасть = Сред(Строка, Позиция + 1); // "Иванович"

Иначе

ЛеваяЧасть = Строка; // пробела нет — строка неделима

ПраваяЧасть = "";

КонецЕсли;

Обратите внимание на смещение на единицу: Лев берёт символы до пробела, не включая его, а Сред начинает со следующего символа после пробела. Если забыть про смещение, в результат попадёт сам пробел, что потом даст лишние незначащие символы при сравнении строк.

Порядок действий
  1. 1
    Получите позицию последнего пробела через СтрНайти с направлением СКонца
  2. 2
    Проверьте, что результат больше нуля
  3. 3
    Отрежьте левую часть функцией Лев(Строка, Позиция - 1)
  4. 4
    Отрежьте правую часть функцией Сред(Строка, Позиция + 1)
  5. 5
    Обработайте ветку, когда пробела в строке нет

Что делать, если пробела в строке нет

СтрНайти возвращает 0, когда подстрока не найдена. Если передать ноль в Лев или Сред без проверки, результат будет неочевидным: Лев(Строка, -1) вызовет ошибку, а Сред(Строка, 1) вернёт всю строку целиком. Поэтому проверка на ноль обязательна в любом рабочем коде.

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

Поиск последнего пробела в старых версиях платформы

В платформах до 8.3.6 параметра направления поиска нет, а функция называется Найти и всегда ищет с начала строки. Там последний пробел находят циклом: перебирают все вхождения и запоминают последнее.

Функция НайтиПоследнийПробел(Строка)

Позиция = 0;

Текущая = Найти(Строка, " ");

Пока Текущая > 0 Цикл

Позиция = Текущая;

Текущая = Найти(Сред(Строка, Текущая + 1), " ");

Если Текущая > 0 Тогда

Текущая = Текущая + Позиция;

КонецЕсли;

КонецЦикла;

Возврат Позиция;

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

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

Сравнение вариантов

СтрНайти с направлением СКонца

Самый короткий и быстрый способ. Требует платформу 8.3.6 и новее.

Цикл с Найти

Работает на любых версиях, включая 8.2. Кода больше, при очень длинных строках медленнее.

СтрРазделить в массив

Удобен, когда нужны сразу все слова строки. Избыточен, если нужна только позиция последнего пробела.

Практический пример: разбор ФИО

Частая задача — выделить фамилию и инициалы из полной строки. Если формат «Фамилия Имя Отчество», фамилия — это часть до первого пробела, а отчество — после последнего. Комбинация двух вызовов СтрНайти решает задачу без циклов.

ФИО = "Петрова Анна Сергеевна";

ПервыйПробел = СтрНайти(ФИО, " ");

ПоследнийПробел = СтрНайти(ФИО, " ", НаправлениеПоиска.СКонца);

Фамилия = Лев(ФИО, ПервыйПробел - 1);

Имя = Сред(ФИО, ПервыйПробел + 1, ПоследнийПробел - ПервыйПробел - 1);

Отчество = Сред(ФИО, ПоследнийПробел + 1);

Учтите, что если в строке только одно слово, первый и последний пробел совпадут (оба равны нулю), и формула для имени даст некорректный результат. Для реальных данных добавьте проверки: есть ли оба пробела и не совпадают ли их позиции.

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

После написания кода проверьте его на граничных данных: строка без пробелов, строка из одного пробела, пробел в конце строки, несколько пробелов подряд. Именно на таких входных данных ломается большинство самописных разборов строк.

Отдельно проверяйте строки, пришедшие извне — из файлов обмена, Excel или веб-сервисов. Там пробел может оказаться неразрывным, и СтрНайти с обычным пробелом его не найдёт, хотя визуально строка выглядит правильно.

Типичные ошибки
01
Поиск без направления СКонца — находится первый пробел, а не последний, и отрезается не та часть строки
02
Отсутствие проверки на ноль — ошибка выполнения или неверный результат, когда пробела нет
03
Забытое смещение на единицу — пробел попадает в результат и ломает сравнения
04
Игнорирование неразрывного пробела — функция не находит визуально видимый пробел
05
Поиск без СокрЛП — хвостовые пробелы дают позицию в конце строки и пустую правую часть
Контрольные точки

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

Строка с несколькими пробелами
Норма

Возвращается позиция именно последнего пробела

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

Возвращается позиция первого пробела

Строка без пробелов
Норма

Результат 0, отрабатывает ветка обработки

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

Ошибка выполнения или пустой результат без пояснения

Строка из внешнего файла
Норма

Пробел находится, части строки корректны

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

Позиция 0 при визуально видимых пробелах — вероятен неразрывный пробел

FAQ

Чем СтрНайти отличается от Найти в 1С?

Найти — старая функция, доступная во всех версиях платформы, ищет только с начала строки. СтрНайти появилась в 8.3.6, поддерживает направление поиска, начальную позицию и номер вхождения. В новых разработках рекомендуется СтрНайти, а Найти сохранена для совместимости.

Как найти последнее вхождение не пробела, а другого символа?

Тем же способом: СтрНайти(Строка, Символ, НаправлениеПоиска.СКонца). Например, последняя точка в имени файла ищется как СтрНайти(ИмяФайла, ".", НаправлениеПоиска.СКонца), что позволяет отделить расширение.

Почему СтрНайти не находит пробел, который виден на экране?

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

Как получить последнее слово строки без поиска позиции?

Разделите строку функцией СтрРазделить(Строка, " ") и возьмите последний элемент массива: Части[Части.ВГраница()]. Способ удобен, когда нужны все слова, но для одного последнего слова поиск с конца короче.

Нумерация символов в 1С начинается с нуля или с единицы?

С единицы. Первый символ строки имеет позицию 1, а значение 0 функции поиска используют как признак «ничего не найдено». Это отличается от многих других языков и является частой причиной ошибок смещения.

Итог

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

Последний пробел в строке 1С находится вызовом СтрНайти(Строка, " ", НаправлениеПоиска.СКонца). Всегда проверяйте результат на ноль, учитывайте смещение на единицу при отрезании частей и очищайте строку от неразрывных пробелов. На платформах до 8.3.6 используйте цикл с функцией Найти.