gifts2017

Функция-обертка для использования объекта VBScript.RegExp в 1С v8

Опубликовал Петр Вел (shmellevich) в раздел Программирование - Практика программирования

При обработке большого количества прайс-листов, приходится работать с разными представлениями данных. Для более простого и унифицированного метода обработки строковых данных, была написана небольшая функция для парсинга, тестирования и замены строк посредством RegExp выражений.

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

Для понимания регуляных выражений можно почитать литературу в итернете.

Также есть простой пример работы с регулярными выражениями 165085

Для проверки регулярных выражений использую RegexBuddy

 

Функция выполняет 3 основных вещи:

1. Тестирование строки по шаблону

    Результат - Истина / Ложь

2. Замена в строке по шаблону

    Результат - строка

3. Получение значений найденых по шаблону:

    Результат - список значений с найденными вхождениями


Параметры:

СтрокаПоиска = ""            - строка, над которой необходимо выполнить действие
ШаблонПоиска = ""            - шаблон, по которому необходимо выполнить действие
Отладка = 0                  - выводить отладочные сообщения при внедрении функции
ВывестиГруппы = Ложь         - в случае работы с группами в выражениях формируютя группы найденых значений
Тестировать = Ложь           - выполнить тестирование по шаблону
RegExp = Неопределено        - при частом использовании функции (в циклах) падает производительность лучше заранее определить СОМ-объект и передавать в качестве параметра
СоздаватьКомОбъект = Истина  - управление необходимостью создания нового СОМ-объект внутри функции
ВыполнитьЗамену = Ложь       - выполняется замена в строке поиска 
СтрокаЗамены = ""            - строка на которую будут заменены найденные выражения


Сама функция:

Функция глRegExp(СтрокаПоиска = ""
               
,ШаблонПоиска = ""
               
,Отладка = Ложь
               
,ВывестиГруппы = Ложь
                ,
Тестировать = Ложь
                ,
RegExp = Неопределено
                ,
СоздаватьКомОбъект = Истина
                ,
ВыполнитьЗамену = Ложь
                ,
СтрокаЗамены = "") Экспорт
   
спкРезультат = Новый СписокЗначений;
    Если (
СтрокаПоиска = "") ИЛИ (ШаблонПоиска = "") Тогда
       
спкРезультат.Добавить("");
        Возврат
спкРезультат;
    КонецЕсли;

    Если
СоздаватьКомОбъект Тогда
       
RegExp = Новый COMОбъект("VBScript.RegExp");
    КонецЕсли;

   
RegExp.IgnoreCase = Истина; //Игнорировать регистр
   
RegExp.Global = Истина; //Поиск всех вхождений шаблона
   
RegExp.MultiLine = Истина; //Многострочный режим

   
RegExp.Pattern = ШаблонПоиска;

    Если
Тестировать Тогда
        Возврат
RegExp.Test(СтрокаПоиска);
    КонецЕсли;

    Если
ВыполнитьЗамену Тогда
        Возврат
RegExp.Replace(СтрокаПоиска,СтрокаЗамены);
    КонецЕсли;

   
Matches=RegExp.Execute(СтрокаПоиска);
   
ЧислоВхождений=Matches.Count();
    Если
ЧислоВхождений>0 Тогда
        Для
к = 0 По ЧислоВхождений-1 Цикл
           
Match = Matches.Item(к);
            Если
ВывестиГруппы Тогда
               
ЧислоВложВхождений = Match.SubMatches.Count();
                Если
ЧислоВложВхождений > 0 Тогда
                   
подСписок = Новый СписокЗначений;
                    Для
к2 = 0 По ЧислоВложВхождений-1 Цикл
                       
SubMatch = Match.SubMatches.Item(к2);
                       
подСписок.Добавить(SubMatch);
                        Если
Отладка Тогда
                           
Сообщить("Результат: " + SubMatch + " Шаблон: " + ШаблонПоиска + " Строка поиска: " + СтрокаПоиска);
                        КонецЕсли;
                    КонецЦикла;
                   
спкРезультат.Добавить(подСписок,Match.Value);
                    Продолжить;
                КонецЕсли;
            Иначе
               
спкРезультат.Добавить(Match.Value);
                Если
Отладка Тогда
                   
Сообщить("Результат: " + Match.Value + " Шаблон: " + ШаблонПоиска + " Строка поиска: " + СтрокаПоиска);
                КонецЕсли;
            КонецЕсли;
        КонецЦикла;
    Иначе
        Если
Отладка Тогда
           
//Сообщить("Вхождений шаблона не найдено - " + ШаблонПоиска);
       
КонецЕсли;
    КонецЕсли;

    Если
спкРезультат.Количество() = 0 Тогда
       
спкРезультат.Добавить("");
    КонецЕсли;

    Возврат
спкРезультат;

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

 

Примеры использования:

а) Тестирование и получение по отдельным группам значений даты: 

    лRegExp = Новый COMОбъект("VBScript.RegExp");
   
_ШаблонДДММГГ = "\b(0?[1-9]|[12][0-9]|3[01])[- /.](0?[1-9]|1[012])[- /.]((19|20)?[0-9]{2})\b";
   
_СтррокаСДатой = "12.08.3013 г.";
    Если
глRegExp(_СтррокаСДатой,_ШаблонДДММГГ,,,Истина,лRegExp,Ложь) Тогда // проверка даты "дд.мм.гг(гг)"
        // брать группы для даты Дата(2,1,0)
       
_спкГрупп = глRegExp(_СтррокаСДатой,_ШаблонДДММГГ,,Истина,,лRegExp,Ложь)[0].Значение;
       
_ОжидаемаяДатаПоставки = Дата(Число(_спкГрупп[2].Значение)
                                     ,
Число(_спкГрупп[1].Значение)
                                     ,
Число(_спкГрупп[0].Значение));
    Иначе
       
_ОжидаемаяДатаПоставки = Дата("00010101");
    КонецЕсли;

 

б) Замена по шаблону:

    лСтрока = "Пример строки с заменой ""двойных"" кавычек на 'одинарные'";
    лСтрока = глRegExp(лСтрока,"""",,,,,,Истина,"'");

 

См. также

Подписаться Добавить вознаграждение
Комментарии
1. Яков Коган (Yashazz) 13.08.13 14:09
Баян. Ищите нормальные публикации по regexp, там были реально полезные вещи, а это сгодится лишь как "ещё одна иллюстрация".
2. Петр Вел (shmellevich) 13.08.13 20:15
(1) Yashazz, Реальные полезные вещи в студию пожалуйста.
Я и не говорил, что моя публикация панацея во всех ситуациях по regexp, а просто "проиллюстрировал", как можно использовать regexp в работе со строками.
Реально полезная вещь - это возможность использовать regexp через нативные (родные) методы 1С, но пока есть 1 вариант RexV8, и за то спасибо автору компоненты.
3. Яков Коган (Yashazz) 14.08.13 11:41
(2) Поисковый движок ИС вам в руки.
Как частный иллюстративный пример это ещё покатит, но, серьёзно говорю, было больше и лучше.
4. Александр Воронов (ya.Avoronov) 19.01.15 11:58
5. Алексей Ива (lolik123) 18.11.15 22:31
Спасибо очень пригодится.