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

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

Как найти кавычки в строке в 1С

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

Поиск кавычек в строке — частая задача при разработке на встроенном языке 1С: разбор CSV-файлов, обработка наименований организаций («ООО «Ромашка»»), валидация пользовательского ввода, формирование SQL-подобных запросов и текста запросов. Сложность в том, что кавычка в 1С — служебный символ: она обрамляет строковые литералы, поэтому напрямую написать " внутри строки нельзя — её нужно удвоить или получить кодом.

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

Почему кавычка в 1С записывается необычно

Во встроенном языке 1С строковый литерал ограничен двойными кавычками. Если внутри такой строки нужна сама кавычка, её удваивают: "ООО ""Ромашка""". Четыре кавычки подряд ("""") — это литерал, содержащий ровно одну кавычку. Это первое, что сбивает новичков: попытка написать СтрНайти(Текст, """) приведёт к синтаксической ошибке, потому что строка окажется незакрытой.

Альтернатива удвоению — функция Символ(34). Число 34 — код двойной кавычки в Unicode. Запись Символ(34) читается легче, чем """", и не ломается при рефакторинге, поэтому в промышленном коде её используют чаще. Оба варианта дают один и тот же символ.

Поиск позиции кавычки через СтрНайти

Базовый сценарий — узнать, есть ли кавычка в строке и где она стоит. Функция СтрНайти(Строка, ПодстрокаПоиска) возвращает номер позиции первого вхождения (нумерация с 1) или 0, если вхождения нет.

Текст = "ООО ""Ромашка""";

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

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

Сообщить("Кавычка найдена на позиции " + Позиция); // позиция 5

Иначе

Сообщить("Кавычек нет");

КонецЕсли;

Тот же пример с литералом вместо Символ(34):

Позиция = СтрНайти(Текст, """");

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

1c
Позиция = СтрНайти(Наименование, Символ(34));
Если Позиция = 0 Тогда
    Сообщить("Кавычки не найдены");
КонецЕсли;

Как найти все кавычки и посчитать их количество

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

Поиск позиций в цикле

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

Текст = "ООО ""Ромашка"" и ИП ""Васильев""";

Позиции = Новый Массив;

НачальнаяПозиция = 1;

Позиция = СтрНайти(Текст, Символ(34), , НачальнаяПозиция);

Пока Позиция > 0 Цикл

Позиции.Добавить(Позиция);

НачальнаяПозиция = Позиция + 1;

Позиция = СтрНайти(Текст, Символ(34), , НачальнаяПозиция);

КонецЦикла;

Подсчёт количества через СтрДлина

Если нужно только количество кавычек, а не их позиции, проще сравнить длину строки до и после удаления кавычек:

КоличествоКавычек = СтрДлина(Текст)

- СтрДлина(СтрЗаменить(Текст, Символ(34), ""));

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

Способы работы с кавычками

СтрНайти + Символ(34)

Подходит для поиска позиции и проверки наличия. Ограничение: возвращает только одно вхождение за вызов.

СтрЗаменить + СтрДлина

Подходит для подсчёта количества и удаления кавычек. Не даёт позиций вхождений.

СтрРазделить(Текст, Символ(34))

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

Замена и удаление кавычек в строке

Частая сопутствующая задача — убрать кавычки или заменить их на другой символ, например на одинарные для выгрузки в текстовый файл:

// Удалить все кавычки

БезКавычек = СтрЗаменить(Текст, Символ(34), "");

// Заменить двойные на одинарные

СОдинарными = СтрЗаменить(Текст, Символ(34), "'");

Будьте осторожны с удалением кавычек из наименований контрагентов: «ООО Ромашка» без кавычек может выглядеть иначе в печатных формах и официальных документах. Если строка участвует в юридически значимых документах, согласуйте формат представления, а не удаляйте символы молча.

Кавычки внутри текста запроса и многострочных строк

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

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Контрагенты.Ссылка

|ИЗ

| Справочник.Контрагенты КАК Контрагенты

|ГДЕ

| Контрагенты.Наименование = &Наименование";

Запрос.УстановитьПараметр("Наименование", "ООО ""Ромашка""");

В многострочных строковых литералах (через символ |) действует то же правило удвоения кавычек. Если текст запроса генерируется динамически и содержит кавычки, ошибку проще всего отловить, выведя итоговый текст в сообщение перед выполнением.

Разбор CSV и строк с вложенными кавычками

При загрузке CSV-файлов значения часто обёрнуты в кавычки, а внутри могут встречаться удвоенные кавычки по стандарту RFC 4180. Простого СтрРазделить(Строка, ";") здесь недостаточно: разделитель может находиться внутри кавычек.

Рабочий подход — посимвольный разбор с флагом «внутри кавычек»:

ВнутриКавычек = Ложь;

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

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

Если ТекущийСимвол = Символ(34) Тогда

ВнутриКавычек = Не ВнутриКавычек;

ИначеЕсли ТекущийСимвол = ";" И Не ВнутриКавычек Тогда

// разделитель полей

КонецЕсли;

КонецЦикла;

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

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

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

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

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

СтрНайти вернула позицию
Норма

Число от 1 до длины строки

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

0 при том, что кавычка в строке видна — проверьте, не ищете ли вы другой тип кавычки (ёлочки, лапки)

Количество кавычек
Норма

Чётное число для корректных парных данных

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

Нечётное число — вероятно, данные обрезаны или повреждены при экспорте

Замена выполнена
Норма

СтрНайти после замены возвращает 0

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

Кавычки остались — возможно, в тексте нестандартные кавычки с другими кодами Unicode

Типичные ошибки
01
Написать СтрНайти(Текст, """) — три кавычки дают синтаксическую ошибку, нужно четыре или Символ(34).
02
Путать двойную кавычку (код 34) с типографскими «ёлочками» (коды 171 и 187) и лапками — СтрНайти их не найдёт, нужен поиск по конкретному коду.
03
Искать в цикле без сдвига начальной позиции — получается бесконечный цикл на первом вхождении.
04
Склеивать строки с кавычками в текст запроса вместо параметров — запрос падает с синтаксической ошибкой.

Отдельная ловушка — типографские кавычки. Пользователи часто копируют текст из Word, где «прямые» кавычки автозаменой превращаются в «ёлочки» (коды 171, 187) или «лапки». Если поиск по коду 34 ничего не находит, а кавычки визуально есть, проверьте код символа: КодСимвола(Строка, Позиция).

Итог

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

Кавычку в строке 1С ищут через СтрНайти(Строка, Символ(34)); в литерале кавычка удваивается. Для всех вхождений — цикл со сдвигом позиции, для количества — разница длин до и после СтрЗаменить. В запросы значения передавайте параметрами, а не склейкой строк.

Частые вопросы

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

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

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

Достаточно сравнить результат с нулём: Если СтрНайти(Текст, Символ(34)) > 0 Тогда ... КонецЕсли;. Отдельной функции «содержит подстроку» в языке нет, поэтому такая проверка — стандартный приём.

Как найти одинарную кавычку (апостроф)?

Одинарная кавычка не является служебным символом в строковых литералах 1С, поэтому её можно писать напрямую: СтрНайти(Текст, "'"). Удвоение и Символ(39) тоже работают, но не обязательны.

Почему СтрНайти не находит кавычку, хотя она видна в строке?

Скорее всего, в тексте типографская кавычка — «ёлочка» или «лапка» с другим кодом Unicode, например из скопированного текста Word. Узнайте код символа функцией КодСимвола() и ищите по нему: Символ(171), Символ(187) и т.д.

Как убрать кавычки только по краям строки, не трогая внутренние?

Проверьте первый и последний символы: если Лев(Текст, 1) = Символ(34), отрежьте его через Сред(Текст, 2); аналогично для последнего символа через Прав(). Готовой функции «обрезать кавычки» в платформе нет.

Работает ли удвоение кавычек в консоли кода и отладчике?

Да, правила строковых литералов едины для всего встроенного языка: и в модуле, и в консоли кода, и в окне вычисления выражений в отладчике. Везде кавычка внутри строки записывается удвоением или через Символ(34).