Часто в разработке мы сталкиваемся с необходимостью преобразовать техническое наименование, написанное в стиле PascalCase (МояНоваяТаблица) или camelCase (мояНоваяТаблица), в читаемый для пользователя формат с пробелами (Моя новая таблица). Например, для автоматического формирования синонимов объектов или представления реквизитов в отчетах. Давайте вместе разберемся, какими способами можно решить эту задачу в 1С, от самых простых до наиболее современных.
Это фундаментальный и универсальный подход, который будет работать на любой версии платформы 1С. Основная идея заключается в том, чтобы пройтись по каждому символу исходной строки и проанализировать его. Если мы встречаем заглавную букву (и это не первый символ строки), мы добавляем перед ней пробел.
Проанализируем ситуацию по шагам:
ВРег() или сравнив его код с кодами заглавных букв алфавита.Посмотрим на пример реализации. Это один из самых наглядных вариантов, где мы также анализируем предыдущий символ, чтобы избежать лишних пробелов.
Функция ПолучитьПредставлениеИзГорбатогоРегистра(ИсходнаяСтрока) Экспорт
Если ПустаяСтрока(ИсходнаяСтрока) Тогда
Возврат ИсходнаяСтрока;
КонецЕсли;
Результат = "";
ПредыдущийСимвол = "";
Для Индекс = 1 По СтрДлина(ИсходнаяСтрока) Цикл
ТекущийСимвол = Сред(ИсходнаяСтрока, Индекс, 1);
// Если текущий символ — заглавная буква, и предыдущий — не заглавная (или не буква),
// то добавляем пробел перед ней (кроме первого символа)
Если Индекс > 1 И
КодСимв(ТекущийСимвол) >= КодСимв("А") И КодСимв(ТекущийСимвол) <= КодСимв("Я") И
НЕ (КодСимв(ПредыдущийСимвол) >= КодСимв("А") И КодСимв(ПредыдущийСимвол) <= КодСимв("Я")) Тогда
Результат = Результат + " " + ТекущийСимвол;
Иначе
Результат = Результат + ТекущийСимвол;
КонецЕсли;
ПредыдущийСимвол = ТекущийСимвол;
КонецЦикла;
Возврат Результат;
КонецФункции
Преимущества этого метода: максимальная совместимость и прозрачность логики. Вы полностью контролируете процесс. Недостатки: может быть менее производительным на очень длинных строках по сравнению с другими методами и требует написания большего объема кода.
Регулярные выражения — это мощный инструмент для поиска и замены в тексте по шаблону. В 1С есть два способа их использования: через встроенные функции платформы (современный способ) и через COM-объект (устаревший, но все еще рабочий способ).
Начиная с версии платформы 8.3.23, в 1С появились нативные функции для работы с регулярными выражениями, такие как СтрЗаменитьПоРегулярномуВыражению(). Это предпочтительный, быстрый и лаконичный способ.
Разберем логику: мы используем шаблон, который находит каждую заглавную букву, за которой следуют строчные, и подставляем перед найденным фрагментом пробел.
Посмотрим на пример:
ИсходнаяСтрока = "МояНоваяСуперТаблица";
// Шаблон "([А-ЯЁ][^А-ЯЁ]*)" ищет заглавную букву [А-ЯЁ],
// за которой следует ноль или более символов, не являющихся заглавными [^А-ЯЁ]*
// Вся найденная группа ($1) заменяется на пробел + саму себя (" $1").
НоваяСтрока = НРег(СтрЗаменитьПоРегулярномуВыражению(ИсходнаяСтрока, "([А-ЯЁ][^А-ЯЁ]*)", " $1"));
// Убираем лишний пробел в начале и делаем первую букву заглавной
НоваяСтрока = СокрЛП(НоваяСтрока);
НоваяСтрока = ТРег(НоваяСтрока); // Или ВРег(Лев(НоваяСтрока, 1)) + Сред(НоваяСтрока, 2);
Сообщить(НоваяСтрока); // Результат: "Моя новая супер таблица"
А вот еще более изящная функция, которая делает то же самое:
Функция СинонимИзИдентификатора(Идентификатор)
// Вся магия происходит в одной строке:
// 1. Сред(Идентификатор, 2) - берем строку со второго символа
// 2. СтрЗаменитьПоРегулярномуВыражению - добавляем пробел перед каждой заглавной буквой
// 3. НРег - приводим все к нижнему регистру
// 4. ВРЕГ(Лев(Идентификатор, 1)) - берем первую букву и делаем ее заглавной
// 5. СокрЛП - убираем возможный пробел в начале
Возврат СокрЛП(ВРЕГ(Лев(Идентификатор, 1)) + НРег(СтрЗаменитьПоРегулярномуВыражению(Сред(Идентификатор, 2), "([А-ЯЁA-Z][^А-ЯЁA-Z]*)", " $1")));
КонецФункции
Если вы работаете на версии платформы старше 8.3.23, вы все еще можете использовать регулярные выражения через COM-объект. Этот метод работает только в ОС Windows.
Разберем по шагам:
COMОбъект("VBScript.RegExp").Pattern), который будет искать все заглавные буквы. Например, "([А-ЯA-Z])".Global в Истина, чтобы замена происходила для всех вхождений в строке, а не только для первого.Replace, где указываем, что найденный символ ($1) нужно заменить на пробел и этот же символ (" $1").СокрЛП().Посмотрим на пример реализации в виде готовой функции:
Функция ПреобразоватьCamelCaseВСтрокуСПробеламиРегЭксп(ВходнаяСтрока) Экспорт
// Проверяем, что входная строка не пустая
Если СтрДлина(ВходнаяСтрока) = 0 Тогда
Возврат ВходнаяСтрока;
КонецЕсли;
// Создаем COM-объект для работы с регулярными выражениями
RegExp = Новый COMОбъект("VBScript.RegExp");
RegExp.Global = Истина;
RegExp.Pattern = "([А-ЯЁA-Z])"; // Ищем любую заглавную букву
// Используем регулярное выражение для поиска заглавных букв и добавления перед ними пробела
Результат = RegExp.Replace(ВходнаяСтрока, " $1");
// Убираем возможный пробел в начале строки
Результат = СокрЛП(Результат);
Возврат Результат;
КонецФункции
Преимущества регулярных выражений: код получается очень коротким и выразительным. Для сложных шаблонов поиска это самый эффективный инструмент. Недостатки: встроенные функции доступны только на новых платформах, а COM-объект имеет зависимость от ОС и может быть медленнее нативных функций.
Рассмотрим сложный случай: строка "HTTPЗапрос". Простые методы, описанные выше, скорее всего, преобразуют ее в "H T T P Запрос", что не всегда является желаемым результатом. Чтобы получить "HTTP Запрос", нужно использовать более сложные шаблоны регулярных выражений, которые учитывают окружение символа (например, ищут заглавную букву, которой предшествует строчная, или за которой следует строчная). Это уже более продвинутый уровень использования, но о нем стоит помнить при работе со сложными идентификаторами.