Иногда возникает необходимость удалить из переменной с типом Строка все специальные символы и оставить только буквы, цифры, тире, подчеркивание и т.п. Например, это нужно при формировании имени файла.
Способов существует много. Некоторые предлагают работать с кодом символов. Известно, что коды букв и цифр находятся в определенном интервале. Таким образом, можно получать код каждого символа, сравнивать его с допустимыми интервалами и в случае необходимости удалять символ.
Я же предлагаю более простой, на мой взгляд, способ. Он заключается в последовательном переборе символов строки и допустимых символов. Для строк с небольшой длиной (а имена файлов редко бывают очень длинными) этот код работает достаточно быстро.
Функция ПолучитьПолноеИмяФайла(знач Контрагент)
//Создаем переменную, в которую поместим все допустимые символы
ДопустимыеСимволы = " абвгдеёжзийклмнопрстуфхцчшщъыьэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_";
ДлинаДС = СтрДлина(ДопустимыеСимволы);
Символ = СтрДлина(Контрагент);
//В переменной Контрагент находится строка, из которой нужно убрать недопустимые символы
//Обойдем каждый символ этой строки, начиная с конца
Пока Символ>0 Цикл
Найдено = Ложь;
//Проверим, есть ли этот символ в перечне допустимых.
//Здесь вместо цикла можно было бы использовать еще функцию Найти()
Для ДопустимыйСимвол = 1 По ДлинаДС Цикл
Если Сред(Контрагент,Символ, 1)=Сред(ДопустимыеСимволы, ДопустимыйСимвол, 1) Тогда
Найдено = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
//Если символ не найден, удаляем его.
Если Не Найдено ТОгда
Контрагент = СтрЗаменить(Контрагент, Сред(Контрагент,Символ, 1), "");
КонецЕсли;
Символ = Символ-1;
КонецЦикла;
Возврат Контрагент;
КонецФункции
//Создаем переменную, в которую поместим все допустимые символы
ДопустимыеСимволы = " абвгдеёжзийклмнопрстуфхцчшщъыьэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_";
ДлинаДС = СтрДлина(ДопустимыеСимволы);
Символ = СтрДлина(Контрагент);
//В переменной Контрагент находится строка, из которой нужно убрать недопустимые символы
//Обойдем каждый символ этой строки, начиная с конца
Пока Символ>0 Цикл
Найдено = Ложь;
//Проверим, есть ли этот символ в перечне допустимых.
//Здесь вместо цикла можно было бы использовать еще функцию Найти()
Для ДопустимыйСимвол = 1 По ДлинаДС Цикл
Если Сред(Контрагент,Символ, 1)=Сред(ДопустимыеСимволы, ДопустимыйСимвол, 1) Тогда
Найдено = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
//Если символ не найден, удаляем его.
Если Не Найдено ТОгда
Контрагент = СтрЗаменить(Контрагент, Сред(Контрагент,Символ, 1), "");
КонецЕсли;
Символ = Символ-1;
КонецЦикла;
Возврат Контрагент;
КонецФункции
Ваш код вообше не работает. отладчик показывает что ваш код возвращает первый символ строки
Добрый день, Азим.
Только что проверили. Код работает.
Не хороший пример.
СтрЗаменить(Контрагент, Сред(Контрагент,Символ, 1), «»); — убирает сразу несколько символов из строки, а отнимается только один (Символ = Символ-1;)
«фыв?фывыф???????фывфы?» Как вы думаете, удалит этот код знаки вопроса?
Да, наш код удалит знаки вопроса.
В вашем примере знаки вопроса будут удалены еще на первой итерации, т.к. последний символ — вопрос, а проверка идет с конца строки.
Действительно, удаляется несколько символов, а отнимается потом только один. Это не приводит к ошибке, т.к. функция СРЕД при выходе за границы строки возвращает «» — пустую строку. В результате функция СТРЗАМЕНИТЬ выглядит так: СТРЗАМЕНИТЬ(Контрагент, «», «»). Это никак не влияет на обрабатываемое значение.
Но Вы правы, наш код не оптимален, можно его доработать так, чтобы не было лишних операций поиска и замены.
Можно проще и без двух вложенных циклов, которые дико тормозят при массовом вызове данной функции.
Предлагайте свой вариант :)
Функция УбратьЛишниеСимволы(Строка1) Экспорт
НовСтрока = «»;
ПравильныеСимволы = «0123456789QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm»;
Для Сч = 1 по СтрДлина(Строка1) Цикл
ТекСимв = Сред(Строка1, Сч, 1);
Если Найти(ПравильныеСимволы, ТекСимв) > 0 Тогда
НовСтрока = НовСтрока + ТекСимв;
КонецЕсли;
КонецЦикла;
Возврат ВРЕГ(НовСтрока);
КонецФункции