Skip to content

Matching #10

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 8, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
135 changes: 114 additions & 21 deletions src/CommonModules/РегВырКлиентСервер/Ext/Module.bsl
Original file line number Diff line number Diff line change
Expand Up @@ -68,49 +68,98 @@
Функция Распознано(Знач Процессор, Знач Текст) Экспорт
ТипСтруктура = Тип("Структура");
ТипСтрока = Тип("Строка");
Вершины = НовыйМешок();
ОбъектПВГ = НовыйНаправленныйПоискВГлубину(Процессор.Орграф, 0);
М = Процессор.Шаблон.Количество();
Вершины = ДостижимыеВершины(Процессор);
Финал = Процессор.Шаблон.Количество();

Для Вершина = 0 По КоличествоВершинОрграфа(Процессор.Орграф) - 1 Цикл
Если НайденоПоискомВГлубину(ОбъектПВГ, Вершина) Тогда
ДобавитьВМешок(Вершины, Вершина);
КонецЕсли;
Для я = 1 По СтрДлина(Текст) Цикл
Символ = Сред(Текст, я, 1);
Совпадения = НовыйМешок();
Для Каждого Вершина Из ЭлементыМешка(Вершины) Цикл
Если Вершина < Финал Тогда
Токен = Процессор.Шаблон[Вершина];
ТипТокена = ТипЗнч(Токен);
Если ТипТокена = ТипСтруктура Тогда
Если Токен.Тип = РегВырПовтИсп.ТипТокенаКлассСимволов() И СимволУдовлетворяетКлассу(Символ, Токен) Тогда
ДобавитьВМешок(Совпадения, Вершина+1);
КонецЕсли;
ИначеЕсли ТипТокена = ТипСтрока И Токен = Символ Тогда
ДобавитьВМешок(Совпадения, Вершина+1);
КонецЕсли;
КонецЕсли;
КонецЦикла;

Вершины = ДостижимыеВершины(Процессор, Совпадения);
КонецЦикла;

Возврат ДостигнутаФинальнаяВершина(Вершины, Процессор);
КонецФункции

Функция Вхождения(Знач Процессор, Знач Текст) Экспорт
фРезультат = Новый Массив;
ТипСтруктура = Тип("Структура");
ТипСтрока = Тип("Строка");
Вершины = ДостижимыеВершины(Процессор);
Финал = Процессор.Шаблон.Количество();
Начало = 0;
ЭтоПотенциальноеСовпадение = Ложь;

Для я = 1 По СтрДлина(Текст) Цикл
Символ = Сред(Текст, я, 1);
Совпадения = НовыйМешок();
Для Каждого Вершина Из ЭлементыМешка(Вершины) Цикл
Если Вершина < М Тогда
Если Вершина < Финал Тогда
Токен = Процессор.Шаблон[Вершина];
ТипТокена = ТипЗнч(Токен);
Если ТипТокена = ТипСтруктура Тогда
Если Токен.Тип = РегВырПовтИсп.ТипТокенаКлассСимволов() И СимволУдовлетворяетКлассу(Символ, Токен) Тогда
Если Начало = 0 Тогда
Начало = я;
КонецЕсли;
ДобавитьВМешок(Совпадения, Вершина+1);
КонецЕсли;
ИначеЕсли ТипТокена = ТипСтрока И (Токен = "." ИЛИ Токен = Символ) Тогда
ИначеЕсли ТипТокена = ТипСтрока И Токен = Символ Тогда
Если Начало = 0 Тогда
Начало = я;
КонецЕсли;
ДобавитьВМешок(Совпадения, Вершина+1);
КонецЕсли;
КонецЕсли;
КонецЦикла;

Вершины = НовыйМешок();
ОбъектПВГ = НовыйНаправленныйПоискВГлубинуПоВершинам(Процессор.Орграф, Совпадения);
Для Вершина = 0 По КоличествоВершинОрграфа(Процессор.Орграф) - 1 Цикл
Если НайденоПоискомВГлубину(ОбъектПВГ, Вершина) Тогда
ДобавитьВМешок(Вершины, Вершина);
Если МешокПуст(Совпадения) Тогда
Если Начало > 0 Тогда
Если ДостигнутаФинальнаяВершина(Вершины, Процессор) Тогда
фРезультат.Добавить(НовоеВхождение(Начало, я, Текст));
КонецЕсли;
Вершины = ДостижимыеВершины(Процессор);
я = я - 1;
Начало = 0;
ЭтоПотенциальноеСовпадение = Ложь;
КонецЕсли;
КонецЦикла;
КонецЦикла;

Для Каждого Вершина Из ЭлементыМешка(Вершины) Цикл
Если Вершина = М Тогда
Возврат Истина;
Продолжить;
КонецЕсли;

ЕстьФинальнаяВершина = Ложь;
Вершины = ДостижимыеВершины(Процессор, Совпадения);
Если ДостигнутаФинальнаяВершина(Вершины, Процессор) Тогда
ЕстьФинальнаяВершина = Истина;
ЭтоПотенциальноеСовпадение = Истина;
КонецЕсли;
Если ЭтоПотенциальноеСовпадение И НЕ ЕстьФинальнаяВершина Тогда
фРезультат.Добавить(НовоеВхождение(Начало, я, Текст));

Вершины = ДостижимыеВершины(Процессор);
я = я - 1;
Начало = 0;
ЭтоПотенциальноеСовпадение = Ложь;
КонецЕсли;
КонецЦикла;

Возврат Ложь;
Если ДостигнутаФинальнаяВершина(Вершины, Процессор) Тогда
фРезультат.Добавить(НовоеВхождение(Начало, СтрДлина(Текст)+1, Текст));
КонецЕсли;

Возврат фРезультат;
КонецФункции
#КонецОбласти

Expand Down Expand Up @@ -162,6 +211,10 @@

Возврат фРезультат;
КонецФункции

Функция НовоеВхождение(Знач НачальнаяПозиция, Знач КонечнаяПозиция, Знач Текст)
Возврат Новый Структура("НачальнаяПозиция, Длина, Значение", НачальнаяПозиция, КонечнаяПозиция - НачальнаяПозиция, Сред(Текст, НачальнаяПозиция, КонечнаяПозиция - НачальнаяПозиция));
КонецФункции
#КонецОбласти

#Область Стек
Expand Down Expand Up @@ -291,6 +344,36 @@
КонецФункции
#КонецОбласти

Функция ДостижимыеВершины(Знач Процессор, Знач Совпадения = Неопределено)
фРезультат = НовыйМешок();

ОбъектПВГ = ?(
Совпадения = Неопределено,
НовыйНаправленныйПоискВГлубину(Процессор.Орграф, 0),
НовыйНаправленныйПоискВГлубинуПоВершинам(Процессор.Орграф, Совпадения)
);

Для Вершина = 0 По КоличествоВершинОрграфа(Процессор.Орграф) - 1 Цикл
Если НайденоПоискомВГлубину(ОбъектПВГ, Вершина) Тогда
ДобавитьВМешок(фРезультат, Вершина);
КонецЕсли;
КонецЦикла;

Возврат фРезультат;
КонецФункции

Функция ДостигнутаФинальнаяВершина(Знач Вершины, Знач Процессор)
Финал = Процессор.Шаблон.Количество();

Для Каждого Вершина Из ЭлементыМешка(Вершины) Цикл
Если Вершина = Финал Тогда
Возврат Истина;
КонецЕсли;
КонецЦикла;

Возврат Ложь;
КонецФункции

Функция ТокеныШаблона(Знач Шаблон)
фРезультат = Новый Массив;

Expand All @@ -302,6 +385,8 @@
ОбработатьКвантификатор(фРезультат, я, Шаблон);
ИначеЕсли Символ = "\" Тогда
ОбработатьЭкранирование(фРезультат, я, Шаблон);
ИначеЕсли Символ = "." Тогда
фРезультат.Добавить(НовыйТокенОбъект(РегВырПовтИсп.ТипТокенаКлассСимволов(), НовыеДанныеТокенаКлассаЛюбыхСимволов()));
Иначе
фРезультат.Добавить(Символ);
КонецЕсли;
Expand Down Expand Up @@ -379,6 +464,10 @@
Возврат Новый Структура("Отрицание, Класс", Отрицание, Новый Соответствие);
КонецФункции

Функция НовыеДанныеТокенаКлассаЛюбыхСимволов()
Возврат Новый Структура("Отрицание, Класс", Ложь, Неопределено);
КонецФункции

Процедура ДобавитьДиапазон(Диапазоны, Знач ЛевыйСимвол, Знач ПравыйСимвол)
Диапазоны.Добавить(Новый Структура("Начало, Окончание", КодСимвола(ЛевыйСимвол), КодСимвола(ПравыйСимвол)));
КонецПроцедуры
Expand All @@ -398,6 +487,10 @@
КонецФункции

Функция СимволПринадлежитКлассу(Знач Символ, Знач Токен)
Если Токен.Данные.Класс = Неопределено Тогда // .
Возврат Истина;
КонецЕсли;

Если Токен.Данные.Класс.Получить(Символ) <> Неопределено Тогда
Возврат Истина;
КонецЕсли;
Expand Down