Coder Social home page Coder Social logo

Comments (21)

alexkmbk avatar alexkmbk commented on August 14, 2024 1

@tormozit Добавил функцию MatchesJSON\НайтиСовпаденияJSON она возвращает результаты поиска в виде JSON текста.
Если третий параметр функции равен Ложь, тогда результат представляет из себя простой массив, иначе, результат представляет из себя массив массивов, где вложенный массив представляет из себя коллекцию результатов, с первым элементом- найденная строка, последующие элементы - подгруппы.
Пример обхода твоего шаблона:

ResJSON = RegExp.MatchesJSON(ТекстГдеИскать, ,Истина);

jsonreader = new JSONReader;
jsonreader.SetString(ResJSON);
res = ReadJSON(jsonreader, True); 

For Each Item In res Do
	//Начало = Вхождение.FirstIndex; // нет аналога
	//Длина = СтрДлина(RegExp.CurrentValue);
	Значение = Item[0];
	ОписаниеФункцииПроцедурыЗначение = Item[1];
	ОписаниеФункцииПроцедуры1Значение = Item[2];
	ОписаниеФункцииПроцедуры2Значение = Item[3];
	ОписаниеФункцииПроцедуры3Значение = Item[4];
	ОписаниеФункцииПроцедуры4Значение = Item[5];
	ОписаниеФункцииПроцедуры5Значение = Item[6];
	ОписаниеФункцииПроцедуры6Значение = Item[7];
			
	КонецЦикла;
	
КонецЦикла;

Компоненту прикладываю к этому сообщению в виде внешних файлов (это не архив компонент).
RegExWin32.zip
RegExWin64.zip

По результатам тестов, через JSON работает в несколько раз быстрее.
Текущая версия тестовая, не для прода.

from regex1caddin.

alexkmbk avatar alexkmbk commented on August 14, 2024 1

Переделал:
RegExWin32.zip
RegExWin64.zip
Теперь вариант обхода будет выглядеть так:

ResJSON = RegExp.MatchesJSON(ТекстГдеИскать);

jsonreader = new JSONReader;
jsonreader.SetString(ResJSON);
res = ReadJSON(jsonreader, False); 

For Each Item In res Do
	Начало = Item.FirstIndex; 
	Длина = Item.Length;
	Значение = Item.Value;
	ОписаниеФункцииПроцедурыЗначение = Item.SubMatches[0];
	ОписаниеФункцииПроцедуры1Значение = Item.SubMatches[1];
	ОписаниеФункцииПроцедуры2Значение = Item.SubMatches[2];
	ОписаниеФункцииПроцедуры3Значение = Item.SubMatches[3];
	ОписаниеФункцииПроцедуры4Значение = Item.SubMatches[4];
	ОписаниеФункцииПроцедуры5Значение = Item.SubMatches[5];
	ОписаниеФункцииПроцедуры6Значение = Item.SubMatches[6];			
КонецЦикла;

Также свойство FirstIndex добавлено в объектную модель обхода результатов.
Результат несколько хуже по скорости чем предыдущий, но все равно намного быстрее чем через объектную модель.

from regex1caddin.

alexkmbk avatar alexkmbk commented on August 14, 2024

@tormozit

Можно ли дополнить объектную модель компоненты избыточными элементами для быстрого подключения компоненты к большому коду, опирающемуся на объектную модель VBScript?

Полной совместимости не получиться, в силу ограничений протокола Native API, который, например, не позволяет возвращать коллекции. Прилагаю файл с кодом, приближенным к вашему, который работает на внешней компоненте:
АналогичныйКодНаRegEx1CAddin.txt

В принципе, можно синтаксис еще глубже приблизить к VBScript если это в самом деле целесообразно с учетом того, что он в любом случе не будет на 100% совместим.

from regex1caddin.

alexkmbk avatar alexkmbk commented on August 14, 2024

@tormozit

Есть ли понимание, насколько эта реализация вычисления регулярных выражений совместима с VBScript ?

В компоненте используется движок от библиотеки Boost.RegEx. Он точно отличается от VBScript.
На текущий момент выявлено расхождение, описанное в этом issue: #4

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

from regex1caddin.

alexkmbk avatar alexkmbk commented on August 14, 2024

@tormozit После перехода на движок PCRE2 вероятно будет полная совместимость с синтаксисом regex101.com, поскольку там судя по всему используется по дефолту та же библиотека. На текущий момент собрана тестовая версия на движке PCRE2 под все поддеживаемые плафтормы - https://github.com/alexkmbk/RegEx1CAddin/releases/tag/13.0

from regex1caddin.

tormozit avatar tormozit commented on August 14, 2024

Хорошо. Но FirstIndex мне необходим. Он используются у меня во многих местах. Есть шансы на его появление?

from regex1caddin.

alexkmbk avatar alexkmbk commented on August 14, 2024

Хорошо. Но FirstIndex мне необходим. Он используются у меня во многих местах. Есть шансы на его появление?

В результатах функции НайтиСовпадения (объектная модель обхода) да, а вот в виде Json есть ли предложения как это можно сделать? Сам Json позволяет, а вот при десериализации в объекты 1С, как это будет выглядеть? в 1С есть требования к ключам стукртур и соответствий, у стрктуры ключ не может начинаться с цифр и т.д., у соответствий ключ уникален. Как вариант можно вообще в виде Json текст не возвращать, а возвращать только интервалы с координатами найденных подстрок. тогда FirstIndex можно будет получить просто из значения первого интервала.

from regex1caddin.

tormozit avatar tormozit commented on August 14, 2024

при десериализации в объекты 1С, как это будет выглядеть?

Это

      {
        "FirstIndex": 86534,
        "Match": {...}
      }

Десериализуется в структуру. Т.е. нужен массив структур, внутри которых одним из свойств является массив подгрупп

from regex1caddin.

alexkmbk avatar alexkmbk commented on August 14, 2024

при десериализации в объекты 1С, как это будет выглядеть?

Это

      {
        "FirstIndex": 86534,
        "Match": {...}
      }

Десериализуется в структуру. Т.е. нужен массив структур, внутри которых одним из свойств является массив подгрупп

Ну да, как вариант. А что думаешь про вариант с возвратом не самого текста, а значений интервалов? А затем получение уже значений с помощью функции Сред? Решается вопрос с экранированием символов (сейчас экранирование сделано, но некоторые накладные расходы на это присутствуют). И мы также исключаем лишнее копирование найденного текста. Это должен быть самый быстрый способ получения результатов.

from regex1caddin.

tormozit avatar tormozit commented on August 14, 2024

Возврат результата в виде диапазонов будет самым оптимальным с точки зрения скорости и потребления ресурсов. Но нужно тщательно проверить корректность расчета этих позиций - символы концов строк CRLF, LF, CR теоритически могут по-
разному считаться в 1С и твоем движке. Поэтому я FirstIndex стараюсь использовать минимально.

from regex1caddin.

alexkmbk avatar alexkmbk commented on August 14, 2024

@tormozit Еще до кучи добавил вариант с возвратом Json с интервалами, этот режим включается, если третьим параметром функции MatchesJSON передать Истина. Тесты показали что в этом режиме выигрыш совершенно не значительный (5-20%), поэтому не уверен что оставлю это в финальной версии.
Обход результатов в этом случае, будет выглядеть так:

ResJSON = RegExp.MatchesJSON(ТекстГдеИскать,,True);

jsonreader = new JSONReader;
jsonreader.SetString(ResJSON);
res = ReadJSON(jsonreader, False); 

For Each Item In res Do
	Начало = Item[0]; 
	Значение = Mid(ТекстГдеИскать, Item[0] + 1, Item[1]-Item[0]);
	Длина = Item[1]-Item[0];
	
	ОписаниеФункцииПроцедурыЗначение = Mid(ТекстГдеИскать, Item[2] + 1, Item[3] - Item[2]);
	ОписаниеФункцииПроцедуры1Значение = Mid(ТекстГдеИскать, Item[4] + 1, Item[5]- Item[4]);
	ОписаниеФункцииПроцедуры2Значение = Mid(ТекстГдеИскать, Item[6] + 1, Item[7]-Item[6]);
	ОписаниеФункцииПроцедуры3Значение = Mid(ТекстГдеИскать, Item[8] + 1, Item[9]- Item[8]);
	ОписаниеФункцииПроцедуры4Значение = Mid(ТекстГдеИскать, Item[10] + 1, Item[11]-Item[10]);
	ОписаниеФункцииПроцедуры5Значение = Mid(ТекстГдеИскать, Item[12] + 1, Item[13]-Item[12]);	
	ОписаниеФункцииПроцедуры6Значение = Mid(ТекстГдеИскать, Item[14] + 1, Item[15]- Item[14]);	
		
КонецЦикла;

Еще в этой сборке добавил синоним Test для функции IsMatch, для совместимости с VBScript.
Можно еще добавить синоним SubMatches, для функции GetSubMatch если это поможет в миграции.

RegExWin32.zip
RegExWin64.zip

from regex1caddin.

alexkmbk avatar alexkmbk commented on August 14, 2024

@tormozit ИМХО, для такого крупного проекта как у тебя, наверное было бы оптимальнее не осуществлять сразу переход на новый движок, а добавить дополнительный слой абстракции, который бы позволял подключать разные механизмы для регулярок. Например, для Windows использовать VBScript, а для Линукса и Мака использовать компоненту, это позволит постепенно адаптировать существующие регулярные выражения под новый движок, с учетом различий от VBScript и при этом переход не затронет основную массу пользователей. В последствии, можно будет полностью перейти на внешнюю компоненту.

from regex1caddin.

tormozit avatar tormozit commented on August 14, 2024

добавить дополнительный слой абстракции

Да. Только так я и внедряю подобные альтернативные механизмы. Без этого я бы утонул в ошибках особенно с учетом отсутствия разветвленной версионности в конфигураторе. Одним из ярких примеров была попытка перехода на RexV8 https://infostart.ru/public/183084/ , которая после долгих мучений была признана провальной и слой абстракции позволил мне быстро вернуться без потерь. Но там была тонкая прослойка. А тут придется делать большую и сложную.

from regex1caddin.

tormozit avatar tormozit commented on August 14, 2024

Вспомнил что JSON в платформе появился с 8.3.6. А у меня поддержка с 8.2.13. Если это не сложно, то было бы неплохо еще добавить функцию MatchesXML. Но если сложно, то оно того точно не стОит, т.к. процент пользователей на 8.2 очень небольшой.

from regex1caddin.

alexkmbk avatar alexkmbk commented on August 14, 2024

Вспомнил что JSON в платформе появился с 8.3.6. А у меня поддержка с 8.2.13. Если это не сложно, то было бы неплохо еще добавить функцию MatchesXML. Но если сложно, то оно того точно не стОит, т.к. процент пользователей на 8.2 очень небольшой.

Кстати для JSON под 8.2 можно воспользоваться этим проектом - https://github.com/legionWFZ/1C-JSON

from regex1caddin.

tormozit avatar tormozit commented on August 14, 2024

В реализации VBScript коллекция SubMatches (подгруппы) всегда содержит столько элементов, сколько подгрупп в выражении. Для не найденных подгрупп - Неопределено.Твой же результат содержит пустую коллекцию

Шаблон ="(?:[^_ЁА-ЯA-Z\d\.]|^)([_ЁА-ЯA-Z][_ЁА-ЯA-Z\d]*(\([^\(\)]*(?:\([^\(\)]*\)[^\(\)]*)*\))?((\.([_ЁА-ЯA-Z][_ЁА-ЯA-Z\d]*)(\([^\(\)]*(?:\([^\(\)]*\)[^\(\)]*)*\))?)|(\[[^\]\[]+?(?:(?:\[[^\]]+?\][^\]\[]*?)*)*\]))*\.?)?$";
Строка = "	              ";
РезультатJSON = MatchesJSON(Строка , Шаблон );

изображение

Попробовал несколько разных шаблонов. Похоже коллекция SubMatches всегда возвращается пустой.

from regex1caddin.

alexkmbk avatar alexkmbk commented on August 14, 2024

@tormozit Можно сравнить с https://regex101.com/, там тоже группы не находит по этому шаблону для всех flavors кроме golang. Для этого шаблона, группы возвращает - #8 (comment)

Если группы в шаблоне найдены, то они будут добавлены, даже если пустые.

from regex1caddin.

tormozit avatar tormozit commented on August 14, 2024

Тогда другой пример
шаблон - (1)(2)?(3)
текст - 13
Результат должен выдать одну группу (вхождение), внутри которой есть подгруппа (Submatch) №1 и подгруппа (Submatch) №3. Как ты вернешь такой массив Submatches? 3-й элемент в массиве может быть только при наличии всех предшествующих. Так что добавлять значение "Неопределено" все равно придется. Так сделай это сразу всегда.
изображение

from regex1caddin.

alexkmbk avatar alexkmbk commented on August 14, 2024

(1)(2)?(3)

Вторая пустая будет, так и работает сейчас. То есть будет 3 группы.
Сергей, есть предолжение issues по тестовой версии на движке pcre2 или вводить в одном issue или в отдельных, но как-то помечать что это pcre2, потому что большинство из найденных проблем не будут касаться текущей стабильной версии, ну или я сам потом добавлю примечание.

from regex1caddin.

tormozit avatar tormozit commented on August 14, 2024

Вторая пустая будет, так и работает сейчас. То есть будет 3 группы.

Это неправильно. Подгруппа может иметь значение <пустая строка> или отсутствовать, что для случая массива может быть обозначено только заменой на значение "Неопределено". Ты сейчас вместо отсутствия возвращаешь <пустая строка>, т.е. искажаешь результат. Подобные грабли мы уже проходили с RexV8.

from regex1caddin.

alexkmbk avatar alexkmbk commented on August 14, 2024

Вторая пустая будет, так и работает сейчас. То есть будет 3 группы.

Это неправильно. Подгруппа может иметь значение <пустая строка> или отсутствовать, что для случая массива может быть обозначено только заменой на значение "Неопределено". Ты сейчас вместо отсутствия возвращаешь <пустая строка>, т.е. искажаешь результат. Подобные грабли мы уже проходили с RexV8.

а понял, согласен

from regex1caddin.

Related Issues (19)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.