Более мощная альтернатива VBScript.RegExp.
Для работы с юникодом V8 использует кроссплатформенную библиотеку ICU, которая помимо прочего, содержит и функционал по работе с регулярными выражениями. По какой-то неизвестной причине, 1С не «вытащила» этот функционал «наружу», и пользоваться им из языка 1С возможности нет.
Однако, как всегда, на помощь приходят ВК.
Представляю свою разработку, которая строит «мостик» из библиотеки ICU в язык 1С. Она может работать и как Native ВК, и как аддин к Снегопату.
Разработка выполнена по технологии «real native», т.е. не просто нативная по терминологии 1С, а использует «родные» методы движка 1С и притворяется штатным объектом 1С. (В семерке так работали 1С++, Rainbow и пр.)
Работа проверялась в толстом и тонком клиенте, и на серверах 32 и 64 бит. Поддерживаются релизы 8.2, 8.3.
Для работы в релизах 8.2 младше 14ого, необходимо скопировать в папку bin файлы icuXXX46.dll из каталогов bin более старших релизов 1С.
Подробнее о регулярных выражениях в ICU можно посмотреть здесь.
Если сравнивать их с обычно используемыми VBScript.RegExp — регулярки от ICU:
- Поддерживает look behind
- Поддерживает поиск по unicode-свойствам символов
- Поддерживает комментарии в выражении
- Более полный и гибкий набор флагов поиска
- Всегда есть с 1С, даже под linux
- Быстрее работает
Для упрощения перехода, часть методов компоненты сделана совместима с VBScript.Regexp.
Таким образом, в существующем коде достаточно поменять создание объекта с Новый COMОбъект(«Vbscript.RegExp») на Новый(«V8RegEx»).
После этого можно пользоваться и остальными методами компоненты, в том числе и split — разбиением строки на части по регулярному выражению.
В поставку входит два файла:
- rex32.dll — для работы в 32-битных клиентах и сервере
- rex64.dll — для работы в 64-битном сервере
Также имеется полная документация в html и текстовом формате.
Основные планы на ближайшее будещее — сделать linux-версию.
Обновлено:
выложена версия 1.0.0.3, в которой устранен ряд ошибок, иногда приводящих к вылету программы.




зачёт. а исходники потом выложить не планируете?
(1)
Планирую, как линукс версию сделаю.
(2) отлично, будет очень интересно подглядеть 🙂
(2)
Я бы тоже глянул, как делается real native.
Ну так то может и хорошо, что просто спрятали, а не как с SQL. Прикинь, Регулярные Выражения от 1С… страшно же…
(5) ADirks, в том и цимус, что они не от 1С 🙂
это, типа, как в 7.7 zlibeng для архивации — приаттачили опенсорсовую длл-ку для внутренних нужд
А есть ли вообще в сети документация по SCOM? Я так понимаю, «притворяться» объектом 1С можно, если библиотека реализует этот одинэсовский креатив? Интересно, как можно вызвать, скажем moxel.dll из стороннего кода..
(7)
Откуда ж документации-то в сети взяться?
Да и нет никакого SCOM на самом деле. Внутри там обычный COM — куча интерфейсов от IUnknown отнаследована, а объекты реализуют кучу интерфейсов, все через QueryInterface получается.
(8) а в линукс-дистрибутиве же то же самое, скорее всего? Я так думал, SCOM, это Sамодельный COM, с целью абстрагироваться от обычного.
Ну на *.cf и *.1cd откуда-то взялся, так что почему нет…
(9)
Я не могу точно сказать, что в 1С имели ввиду под аббревиатурой SCOM.
Делать его самодельным — ну я не знаю. Сам по себе COM прост как три рубля, и довольно легко имплементируется.
(9) Evil Beaver,
в линукс COM нет
(11)
По сути своей (если не брать деталей межпроцессного обмена) — COM очень прост.
Он описывает правила вызова методов интерфейсов, подсчета ссылок на объект, и интерфейс IUnknown.
Вот всё, что я хотел сказать о COM.
(11) andrewks, дык и я про что. COM нет, а SCOM, скорее всего есть.
Помнится, давно, я пытался извлечь из 1С-овской dll набор типов в виде type library. Так вот, ни один инструмент не опознал в ней COM-dll и ничего о внутренностях не сказал. Я это дело забросил, а вообще — жутко интересно, как можно правильно вызвать код из родной 1С-овской dll.
(12) да это понятно
(13)
TypeLibrary — это уже OLE, которое базируется на COM.
Сам COM для работы ни в каких type library не нуждается.
(13) Evil Beaver, ну так dll-ка и не обязана всегда иметь COM-интерфейс, в общем случае
Для совместимости RegExMatch.SubMatches(0) должен возвращать Неопределено в случае, если подгруппа не найдена. Сейчас возвращает пустую строку.
(17)
Хм, странно. Вообще, по моей задумке должно было исключение кидать.
Приведи пожалуйста пример для ясности, я проверю.
(18) Речь о необязательных подгруппах.
Должно выдавать Неопределено, а не Строка.
Нет, все правильно выдает "Строка".
Найдено одно совпадение, захвачена группа — пустая строка.
В javascript себя так же ведет:
Показать полностью
Ну я говорю про VBScript.RegExp, который очень распространен в коде 1С. Так вот он работает именно так, как я описал, что легко проверить в моем примере, заменив первую строку.
Кстати для новых типов объектов неплохо бы обеспечить преобразование к строке. Модифицировав мой пример
получаем исключение
Преобразование значения к типу Строка не может быть выполнено
(20) Я конечно не специалист в JavaScript, но возможно в твоем коде сообщается тип первой Группы, а не первой Подгруппы первой Группы.
(22)
В javascript — если регэксп не глобальный, возвращает объект, где [0] — все совпадение, [1] и далее — подгруппы.
А с (19) я наверное не смогу ничего делать.
Налицо разная реализация самих регекспов в разных библиотеках.
То есть ICU и javascript считают, что захвачена подгруппа — пустая строка, VBScript считает, что подгруппа не захвачена. Я же не полезу внутрь ICU переделывать реализацию самих регэкспов. Или VBScript всегда для подгрупп — пустых строк возвращает Неопределено? Если это так, то можно и сделать в этом частном случае.
Преобразование одного результата в строку — как его сделать? Выдавать значение свойства Value? Или выдавать «COMОбъект», как у VBScript?
(20) а у меня undefined, что в html страничке, что в phantomjs.
(23) Преобразование к строке есть насколько я знаю у всех типов 1С. Раз уж имитировать родной тип, то и эту особенность следует учесть. По умолчанию для всех типов платформы преобразование к строке возвращает имя типа. Думаю в нашем случае нужно сделать также.
> VBScript всегда для подгрупп — пустых строк возвращает Неопределено?
Нет. Неопределено возвращается в качестве подгруппы, если она необязательная и была не найдена. Для пустых строк возвращается пустая строка. Что очень логично, т.к. есть возможность различать
— не найденную необязательную подгруппу
— найденную пустую подгруппу
Такой код для VBScript.RegExp
выдает
Строка
Не определено
(24)
Ну тут уже в-принципе, не так важно, что в разных реализациях javascript выдает, важно, как себя ведет ICU.
А в ICU вообще невозможно отследить, захватилась или нет группа, ибо она всегда захватывается. Так что это тот порог, на котором борьбу за совместимость придется остановить.
Супер
Вопрос по производительности:
На сколько (%)?
(28)
На некоторых тестах первая версия RexV8 обгоняла VBScript.Regexp не на проценты, а в 5 раз, а на других тестах — проигрывала в 2 раза. Вот жду, когда tormozit сделает замеры на новой версии.
Офигеть! 🙂
Класс!
«Просмотра назад» в VBScript.RegExp бывало очень не хватало, да..
Хорошая вещь… автору +
Какая цель? Что с помощью этого можно делать?
Провел сравнительный замер новой версии следующим кодом в консоли кода ИР
Показать
Получил
Окончание замера «Замер_30» — Длительность = 1.135с, Среднее = 0.00001135с
Окончание замера «Замер_31» — Длительность = 2.849с, Среднее = 0.00002849с
Окончание замера «Замер_32» — Длительность = 1.08с, Среднее = 0.0000108с
Окончание замера «Замер_33» — Длительность = 2.538с, Среднее = 0.00002538с
Т.е. этот объект в 2-3 раз быстрее работает, чем VBScript.RegExp.
(34)
Огромное спасибо за тесты!
Результаты радуют.
Такой код приводит к недопустимой операции (переполнению стека?). 8.2.18.51
Показать
Problem Event Name: APPCRASH
Application Name: 1CV8.exe
Application Version: 8.2.18.51
Application Timestamp: 513e4ca9
Fault Module Name: icudt46.dll
Fault Module Version: 4.6.1.5
Fault Module Timestamp: 50751a3d
Exception Code: c0000005
Exception Offset: 0029007a
OS Version: 6.1.7601.2.1.0.256.1
Locale ID: 1049
Additional Information 1: 0a9e
Additional Information 2: 0a9e372d3b4ad19135b953a78882e789
Additional Information 3: 0a9e
Additional Information 4: 0a9e372d3b4ad19135b953a78882e789
Показать
Видимо внутренний кэш не имеет контроля роста.
Выложил версию 1.0.0.3.
Устранен ряд ошибок, иногда приводящий к вылету программы.
Будет хорошо, если в описании указать про неполную совместимость с VB (пустая строка против Неопределено для не найденных необязательных подгрупп). Речь про этот фрагмент
Дальше я бы дописал «Однако следует учитывать, что при получении не найденных необязательных подгрупп метод SubMatches в VBScript возвращает Неопределено, а в V8RegExp возвращает пустую строку».
В новой версии 1.0.0.3 тест (36) по-прежнему приводит к падению.
(39)
Странно, у меня не падает.
Напиши версию 1С и архитектуру (32/64)
(40) Да. Теперь в чистом виде (36) не воспроизводится, но в грязном воспроизводится. Пока могу лишь описание ошибки предоставить (ОС Win7 32b)
Problem Event Name: APPCRASH
Application Name: 1CV8.exe
Application Version: 8.2.18.51
Application Timestamp: 513e4ca9
Fault Module Name: V8RegEx32.dll
Fault Module Version: 1.0.0.3
Fault Module Timestamp: 5194801f
Exception Code: c0000005
Exception Offset: 00006bb7
OS Version: 6.1.7601.2.1.0.256.1
Locale ID: 1049
Additional Information 1: 0a9e
Additional Information 2: 0a9e372d3b4ad19135b953a78882e789
Additional Information 3: 0a9e
Additional Information 4: 0a9e372d3b4ad19135b953a78882e789
Показать
Позже выясню детально, какое еще условие нужно для воспроизведения.
Несколько часов пытался, но не удалось сделать чистый пример. Ошибка точно есть (остаток от первоначальной). Сделал демо-базу из ИР, где в включен режим использования этого RegExp, и снял 2 видеоролика для демонстрации багов, насколько было возможно отвязал от логики ИР. . Я готов показать более подробно teamviewer’у, если есть желание.
Вывел в чистом виде остаток бага. Так
Показать
возникает недопустимая операция
Problem Event Name: APPCRASH
Application Name: 1CV8.exe
Application Version: 8.2.18.51
Application Timestamp: 513e4ca9
Fault Module Name: rex32.dll
Fault Module Version: 1.0.0.3
Fault Module Timestamp: 5194801f
Exception Code: c0000005
Exception Offset: 00006bb7
OS Version: 6.1.7601.2.1.0.256.1
Locale ID: 1049
Additional Information 1: 0a9e
Additional Information 2: 0a9e372d3b4ad19135b953a78882e789
Additional Information 3: 0a9e
Additional Information 4: 0a9e372d3b4ad19135b953a78882e789
Показать
Ну что, есть надежда на исправление бага (43)?
При выполнении поиска с таким шаблоном
[(DisplayName(«(w+»))s*:s*w+,)?Description(«(.*?)»)s*[#k8SjZc9Dxk ]+]s*classs+(w+)s*:s*w+s*{(.*?)};ругается
Ошибка при вызове метода контекста (Выполнить): Не удалось создать регулярное выражение. Строка 1, Позиция 106, текст до: ‘+)s*:s*w+s*’, после: ‘{(.*?)};’
Так фигурные скобки тоже надо экранировать
\{(.*?)\};Показать полностью
(46) еще одно отличие от MS реализации. Там это не вызывает ошибки. Теперь вспомнил, что фигурные скобки для числа повторов используются. Но видимо в зависимости от контекста они автоматом распознаются в других реализациях как символы. Ок, буду везде их экранить для надежности.
(33) It-developer,
подумай, ты же как никак It-developer
Ждать ли нам стабильной версии?
Ну что, когда? =)
У кого-нибудь работает под 8.3.4. ? При подключении компоненты под 8.3.4.389 падает платформа. ОС:Win7 Pro x64.
(0) orefkof,
а почему не Новый(«V8RegExp«) ? 🙂
Платформа 8.3.4.408, при подключение ВК(ПодключитьВнешнююКомпоненту(ПутьКВК, «RegEx», ТипВнешнейКомпоненты.Native)) платформа вылетает в дамп!!!.
Можно ли как нить исправить этот косяк?
Отличная штука!
Странно что в 1С нет штатного объекта для регулярок.
Мне не хватает до полного счастья только версии под линукс и параметра /U (Ungreedy), его сложно реализовать?
Была платформа 8.2.19 — все работало нормально.
Обновились на 8.3.15 — начал падать 1с в момент подключения внешней обработки…
(55)
8.3.15 пока не поддерживается. Следите за обновлениями.
(56) ну хотя бы ориентир по срокам какой?
И желательно в описании написать до какой версии поддерживается…
(57)
Проверяй —
Для 8.3.4.x, 8.3.5.x.
Я наскоро проверял на 8.3.5.823, на клиенте. На 64битном сервере не проверял.
(58) да теперь все работает.
64х битного сервера к сожалению нет, поэтому не могу проверить.
А на 32х битном все работает отлично.
Спасибо за оперативность)
PS Касательно линукс версии — тоже было бы круто поскорей увидеть)
(58) Спасибо. Я тоже сейчас использовал на 8.3.4.
Здравствуйте, не могли бы вы предоставить исходники данной компоненты? Очень интересует работа real native компонент, необходимо интегрировать свое окно в существующую форму 1С, через FindWindowEx это сделать проблематично, тк там куча окон с одинаковыми классами у всех ЭУ, нужно хотя бы получить HWND конкретной формы, судя по FormEx это возможно. Нашел исходники 1С++, но они для 7.7 и там, судя по инициализации компоненты с IDispatch она загружается как COM-объект, а не как Native… Собственно интересуют даже не столько исходники конкретной компоненты, сколько технология создания real-native компонент. Спасибо! Мои контакты: kolayuk at gmail.com
(58) Компонента успешно проработала с сентября месяца, а вчера внезапно началась валиться без выдачи каких-либо сообщений и исключений, просто программа тупо завершает работу. Пришлось в срочном порядке переключать на виндовый VBScript.RegExp.
Если интересно, вот набор регулярок
МассивШаблонов.Добавить(«(евро[а-яa-z]{0,5}s{0,1}[а-яa-z]{0,15}s{0,1}отдел[а-яa-z]{0,5}s{0,1})»); МассивШаблонов.Добавить(«(итальян[а-яa-z]{0,5}s{0,1}[а-яa-z]{0,10}s{0,1}кафел[а-яa-z]{0,5}s{0,1})»); МассивШаблонов.Добавить(«(встроен[а-яa-z]{0,5}s{0,1}[а-яa-z]{0,10}s{0,1}шкаф[а-яa-z]{0,5}s{0,1}купе[а-яa-z]{0,5}s{0,1})»); МассивШаблонов.Добавить(«(отдел[а-яa-z]{0,5}s{0,1}[а-яa-z]{0,15}s{0,1}евро[а-яa-z]{0,5}s{0,1})»); МассивШаблонов.Добавить(«(тепл[а-яa-z]{0,5}s{0,1}[а-яa-z]{0,10}s{0,1}пол[а-яa-z]{0,5}s{0,1})»); МассивШаблонов.Добавить(«(евроs?ремон[а-яa-z]{0,5}s?)|(evros?ремон[а-яa-z]{0,5}s?)»); МассивШаблонов.Добавить(«(ремон[а-яa-z]{0,5}s{0,1}[а-яa-z]{0,10}s{0,1}евро[а-яa-z]{0,5}s{0,1})»); МассивШаблонов.Добавить(«(сост[а-яa-z]{0,5}s{0,1}[а-яa-z]{0,15}s{0,1}отлич[а-яa-z]{0,5}s{0,1})|(отлич[а-яa-z]{0,5}s{0,1}[а-яa-z]{0,15}s{0,1}сост[а-яa-z]{0,5}s{0,1})»); МассивШаблонов.Добавить(«(отлич[а-яa-z]{0,5}s{0,1}[а-яa-z ]{0,35}s{0,1}ремон[а-яa-z]{0,5}s{0,1})»); МассивШаблонов.Добавить(«([а-яa-z]{0,15}качествен[а-яa-z]{0,5}s{0,1}[а-яa-z ]{0,35}s{0,1}ремон[а-яa-z]{0,5}s{0,1})»); МассивШаблонов.Добавить(«(соврем[а-яa-z]{0,5}s{0,1}[а-яa-z ]{0,35}s{0,1}ремон[а-яa-z]{0,5}s{0,1})|(ремон[а-яa-z]{0,5}s{0,1}[а-яa-z ]{0,35}s{0,1}соврем[а-яa-z]{0,5}s{0,1})»); МассивШаблонов.Добавить(«(дорогой[а-яa-z]{0,5}s{0,1}[а-яa-z ]{0,35}s{0,1}ремон[а-яa-z]{0,5}s{0,1})|(ремон[а-яa-z]{0,5}s{0,1}[а-яa-z ]{0,35}s{0,1}дорогой[а-яa-z]{0,5}s{0,1})»); МассивШаблонов.Добавить(«(дизайн[а-яa-z]{0,5}s{0,1}[а-яa-z ]{0,35}s{0,1}ремон[а-яa-z]{0,5}s{0,1})|(ремон[а-яa-z]{0,5}s{0,1}[а-яa-z ]{0,35}s{0,1}дизайн[а-яa-z]{0,5}s{0,1})»); Для каждого ЭлементМассива Из МассивШаблонов Цикл RegExp.Pattern = ЭлементМассива; Результат = RegExp.Test(ТекстовоеСодержимое); Если Результат Тогда //Результат.Count > 0 ………… здесь что-то делаем КонецЕсли; КонецЦикла; //Для каждого ЭлементМассива ИзПоказать
Платформа 8.3.5.1383. Очень странно. Виндовый объект отрабатывает спокойно, причём ТекстовоеСодержимое предварительно очищается от всех небуквенно-цифровых символов.
(62) Так я же еще в (41),(45) предупреждал. Автор до сих пор динамит багу =)
Давно ещё приметил эту разработку, а сейчас вот случай представился. И первый же случай не работает 🙁 На выражение
ругается:
на 1С:Предприятие x32 сервере 8.3.x, в многопользовательском режиме, использование этой компоненты приводит к падению рабочих процессов 1с, пришлось вернуться на regexp
А как можно ПодключитьВнешнююКомпоненту через макет?
Отвечаю сам себе.
Отлично подключается zip-архив с манифестом из общего макета.
Выложите исходники, пожалуйста!
Версии под Linux очень не хватает =(
(68)
Сейчас глянул исходники — это ужас. Я сейчас сам там с трудом разберусь — что нужно, что не нужно, что можно выкладывать, а что нет.
Давайте я постараюсь до Нового Года как-то решить вопрос. Сейчас есть мысль на базе нового снегопата сделать по аналогии работу в предприятии, там и регулярки тогда будут.
На сервере х64 Дерево результата заполняется мусором (8.3.7), на x32 все в порядке. Дело явно в ерунде! Может все-таки имеет смысл выложить исходники? Компонента крайне полезная! Автору Большое спасибо!
(70) Pupkindt,
Дело то на самом деле не в исходниках. Эта ВК — костыли, причём релизо-зависимые. Как одинэсники-то докатились до жизни такой, что стоя уже обеими ногами в 21 веке — не имеют в своём распоряжении такого элементарного инструмента, как регулярные выражения? Они сейчас чуть не в каждой микроволновке есть. Даже С++ — и то уже включил их в стандарт языка — да, даже в С++ они теперь уже не сторонняя библиотека, а часть языка. И как я показал, внутри движка они есть. Но партия решила — одинэсники обойдутся.
Приложение умирает при «ПодключитьВнешнююКомпоненту».
Только у меня?
Имя события проблемы: BEX
Имя приложения: 1CV8C.exe
Версия приложения: 8.3.7.2008
Отметка времени приложения: 56f1d2b8
Имя модуля с ошибкой: StackHash_0a9e
Версия модуля с ошибкой: 0.0.0.0
Исходников компоненты не будет?
Да, я еще в 2015 году просил. Пусть лучше будут хоть какие-то исходники, чем ничего.
Спасибо!
Добрый день, после обновления платформы с 8.3.10 до 8.3.11.2867 (по крайней мере других изменений в системе и коде не произошло) компонента «отвалилась» 🙂 метод ПодключитьВнешнююКомпоненту() возвращает Ложь. При попытке перерегистрировать «ругается» на то, что «не найдена указанная процедура» (см. рис. во вложении).
Возможно, кто-то сталкивался с подобным, буду рад советам/комментариям. Спасибо!
наткнулся на не корректную работу компоненты… как бы понять по используемому сейчас dll файлу, последняя ли это версия?
(76) Сравните с той версией, что находится на сайте автора
(77) вчера перешёл на использование VBScript.RegExp и проблема ушла. а файлы сейчас сравнил — совпадают (а за ссылку спасибо, вчера не смог найти раздел скачивания)