[CDR 2017-2021] Использование нескольких re.pattern с одним regexp .

tohaa

Участник
Топикстартер
Сообщения
229
Реакции
8
Возможно ли использование нескольких re.pattern с одним regexp объектом?
Хочу редактировать текст с использованием нескольких регулярных выражений.
Т.е. за один шаг цикла производить проверку по нескольким паттернам. Для экономии времени за счет сокращения циклов проверки.
Подскажите пожалуйста.
 

splxgf

12 лет на форуме
Сообщения
7 742
Реакции
3 424
ну чтобы совсем несколько выражений такого нет, но по очереди хоть запроверяйтесь, в т.ч. в цикле.
 

eugeny

15 лет на форуме
Сообщения
859
Реакции
210
Давайте представим себе вашу ситуацию: regexp объект проверяет фрагмент текста на соответствие паттерну. Но ему надо также проверить и на соответствие другому паттерну. Причем если соответствует паттерну №1 сделать замену №1, если №2 — замену №2.
Где вы хотите выиграть во времени? Дробить текст на куски проверять его на два паттерна по очереди? Ну вы можете просто два раза прогнать текст по очереди через каждый паттерн.
Единственный вариант создать свой regexp объект, который будет возвращать атрибут соответствия (№1 или №2) и позиции начала и конца совпадения. Подобные вещи решаются с помощью javascript, например. Но реализация подобного на ВБА не стоит свеч.
Аналог на javascript вашей задачи можно найти во многих Rich Text Editor для Веба. Например, Draft.js, он хранит очень подробную модель всего текста с разметкой, стилями, декораторами и.т.п.
 

tohaa

Участник
Топикстартер
Сообщения
229
Реакции
8
c
Давайте представим себе вашу ситуацию: regexp объект проверяет фрагмент текста на соответствие паттерну. Но ему надо также проверить и на соответствие другому паттерну. Причем если соответствует паттерну №1 сделать замену №1, если №2 — замену №2.
Где вы хотите выиграть во времени? Дробить текст на куски проверять его на два паттерна по очереди? Ну вы можете просто два раза прогнать текст по очереди через каждый паттерн.
Единственный вариант создать свой regexp объект, который будет возвращать атрибут соответствия (№1 или №2) и позиции начала и конца совпадения. Подобные вещи решаются с помощью javascript, например. Но реализация подобного на ВБА не стоит свеч.
Аналог на javascript вашей задачи можно найти во многих Rich Text Editor для Веба. Например, Draft.js, он хранит очень подробную модель всего текста с разметкой, стилями, декораторами и.т.п.
Сейчас я делаю три прохода по тексту просто вызывая подпрограмму трижды с разным паттерном. Текст обычно от 300 до 2000 строк. Каждый построчный перебор занимает около 10 секунд. В сумме это более 30 секунд. Ищу способ обработки текста быстрее.
 

DukereD

макрософил
Сообщения
462
Реакции
114
c

Сейчас я делаю три прохода по тексту просто вызывая подпрограмму трижды с разным паттерном. Текст обычно от 300 до 2000 строк. Каждый построчный перебор занимает около 10 секунд. В сумме это более 30 секунд. Ищу способ обработки текста быстрее.
вам же подсказали. делать 3 проверки в одном вызове. проще переписать вызов процедуры. передавайте строчный массив паттернов и внутри пробега по тексту пробегайте по этому массиву и делайте 3 подмены в порядке очереди
 

splxgf

12 лет на форуме
Сообщения
7 742
Реакции
3 424
Сейчас я делаю три прохода по тексту просто вызывая подпрограмму трижды с разным паттерном. Текст обычно от 300 до 2000 строк. Каждый построчный перебор занимает около 10 секунд.
Покажите ваш код.
 

tohaa

Участник
Топикстартер
Сообщения
229
Реакции
8
Покажите ваш код.
Код:
Dim s As Shape
Set re = CreateObject("VBScript.RegExp")
re.Pattern = "class=""fil\d{1,2}\s{0,1}.{0,4}"""

Set s = ActiveDocument.ActiveShape
    
    For Each L In s.Text.Story.Lines

    ns = L.Text

    If InStr(L.Text, "<g id=""main"">") Then doreplace = True
    If InStr(L.Text, "<g id=""print1"">") Then doreplace = False

 
    If doreplace Then
    If re.Test(L.Text) Then ns = re.Replace(L.Text, "class=""main"" ")
    Else: ns = re.Replace(L.Text, "class=""print"" ")
    
    End If
    
    ss = ss & ns
    Next L
    s.Text.Story = ss

End Sub
 

dastin

Некромант-любитель
12 лет на форуме
Сообщения
2 145
Реакции
2 043
Ищу способ обработки текста быстрее.
- Не корысти ради, а токмо волею пославшей мя супруги! интереса - попробуйте сделать тоже самое, но в версии Х7
Сколько выйдет супротив 30 секунд?
 

DukereD

макрософил
Сообщения
462
Реакции
114
- Не корысти ради, а токмо волею пославшей мя супруги! интереса - попробуйте сделать тоже самое, но в версии Х7
Сколько выйдет супротив 30 секунд?
типа в версии X7 работало быстрее? ))
 

dastin

Некромант-любитель
12 лет на форуме
Сообщения
2 145
Реакции
2 043
  • Спасибо
Реакции: DukereD

splxgf

12 лет на форуме
Сообщения
7 742
Реакции
3 424
Возможно все вышеперечисленное укладывается в пару regexp без всяких условий и проверок.
Сильно много лишних проверок InStr, regexp самодостаточный инструмент и возможно более оптимизированный.
Можно попробовать оставить только две строчки предварительно меняя паттерн для поиска
ns = re.Replace(ns, "class=""main"" ")
ns = re.Replace(ns, "class=""print"" ")

ss = ss & ns ' деление на строки теряется, может так и надо.
 

_MBK_

Пикирующий бомбардировщик
15 лет на форуме
Сообщения
33 228
Реакции
10 851
А для чего вообще такое странное надо? Меня терзают смутные сомнения, что вы какой то парсер xml/html прямо в кореле хотите сделать???
 

splxgf

12 лет на форуме
Сообщения
7 742
Реакции
3 424
Потестировать выражения можно на regex101: build, test, and debug regex и не обязательно делить построчно, можно весь текст целиком обрабатывать в некоторых разумных пределах.
 

_MBK_

Пикирующий бомбардировщик
15 лет на форуме
Сообщения
33 228
Реакции
10 851
Ну так я и думал 'fp'
Подарили чукче Камаз, через некоторое время спрашивают - ну как, мол, хорошая машина? - Ой, шибко хорошая однако: большая, прочная, теплая! Собаки только шибко устают.
 

splxgf

12 лет на форуме
Сообщения
7 742
Реакции
3 424
Еще есть у RegExp свойство Multiline

Ваша задача решается одной заменой, просто курите документацию.
 
  • Спасибо
Реакции: tohaa

splxgf

12 лет на форуме
Сообщения
7 742
Реакции
3 424
В поиске могут использоваться круглые скобки, которые обозначают группы поиска, потом в замене их можно выстраивать в нужном порядке и в том числе встраивать дополнительный текст.
 
  • Спасибо
Реакции: tohaa

splxgf

12 лет на форуме
Сообщения
7 742
Реакции
3 424
Не уверен что правильно, но для поиска может подойти выражение
Код:
(<g id="print\d*">)([\n]*)(.*)(class="print")(.*)([\n]*)(.*)(class="print")(.*)
Проверку и замену выстраивайте уже на своих данных.
 
  • Спасибо
Реакции: tohaa

tohaa

Участник
Топикстартер
Сообщения
229
Реакции
8
Не уверен что правильно, но для поиска может подойти выражение
Код:
(<g id="print\d*">)([\n]*)(.*)(class="print")(.*)([\n]*)(.*)(class="print")(.*)
Проверку и замену выстраивайте уже на своих данных.
Попробую использовать этот вариант. Благодарю.