| View previous topic :: View next topic |
| Author |
Message |
yozhik

Joined: 04 May 2014 Posts: 347 Location: Электросталь
|
(Separately) Posted: Mon Jul 20, 2026 13:05 Post subject: |
|
|
| Orion9 wrote: | | Сначала заменить _|_78_| на \n. |
Да, но это в силе только для одного лога. А в другом логе начальное число будет другим и оно заранее неизвестно. Т.е. не соблюдается вот это условие:
| Batya wrote: | | начало табличного текста и начало каждой строки начинается с одинакового фрагмента, который меняется для каждого лога |
Я, кажется, понял как нужно сделать. Сейчас только проверю работоспособность в NPP и дооформлю пост. (А потом и ещё и болванную оптимизацию прокомментируем)). _________________ Amo ergo sum |
|
| Back to top |
|
 |
Batya

Joined: 15 Dec 2004 Posts: 2235 Location: Москва, Россия
|
(Separately) Posted: Mon Jul 20, 2026 13:20 Post subject: |
|
|
Orion9
Можно. Только я заранее не знаю точное значение начального фрагмента ("_|_78_|_"). Вместо "78" может быть любое число. При этом просто менять все числа я не могу. Надо поменять именно фрагмент, находящийся в начале, но который заранее не известен. _________________ Нет, я не сплю. Я просто медленно моргаю. |
|
| Back to top |
|
 |
yozhik

Joined: 04 May 2014 Posts: 347 Location: Электросталь
|
(Separately) Posted: Mon Jul 20, 2026 13:58 Post subject: |
|
|
Batya
 Условия списком, для удобства 1. Обработка макросом.
2. Строки таблицы могут быть на отдельных строках, а могут быть склеены.
3. Начало табличного текста и начало каждой строки начинается с одинакового фрагмента, который меняется для каждого лога.
4. Количество строк всегда разное.
5. Количество склеенных строк заранее не известно.
6. Начальный фрагмент можно заменить, а можно и оставить.
Я бы сделал так. Разъединяю склеенные строки. Запускаю несколько раз следующую замену (найти/заменить):
| Code: | (?m-s)^(_\|_\d+_\|_)(.+)(\1.+?)$
\1\2\r\n\3 |
За каждый проход эта регулярка будет «отщипывать» нужный нам блок от конца строки. Запускаю «несколько раз» — т.е. столько, сколько нужно. 100 раз, 200 раз. В зависимости от максимально возможного кол-ва склеенного. В конце это приведёт к требуемому виду:
| Code: | _|_начало_|...
_|_начало_|...
_|_начало_|...
и т.п. |
Условие 5 соблюдается, только придётся уточнить максимум.
Это по сути аналог обработки циклом в скрипте. Но у нас же макрос, а значит нас не заботит кол-во проходов регуляркой по тексту. И 100, и 200 отработают в долю секунды. Просто откопировать эту строку макроса столько раз, сколько нужно.
Этим соблюдается условие 3. Ведь, если я правильно понял, в каждом логе _|_начало_| будет одинаковым для всего лога. Т.о. мы не рискуем промахнуться.
После этой обработки можно и пустые строки удалить, и извлечь нужные блоки в отдельную вкладку, если помимо блоков там есть ещё ненужный текст. _________________ Amo ergo sum
Last edited by yozhik on Mon Jul 20, 2026 14:02; edited 1 time in total |
|
| Back to top |
|
 |
Orion9

Joined: 01 Jan 2024 Posts: 1220
|
(Separately) Posted: Mon Jul 20, 2026 14:01 Post subject: |
|
|
| yozhik wrote: | | А в другом логе начальное число будет другим и оно заранее неизвестно. |
Если табличная часть из лога извлекается пользователем, она всегда будет ему известна | yozhik wrote: | | (А потом и ещё и болванную оптимизацию прокомментируем) |
Да. Очень бы этого хотелось ) |
|
| Back to top |
|
 |
yozhik

Joined: 04 May 2014 Posts: 347 Location: Электросталь
|
(Separately) Posted: Mon Jul 20, 2026 14:06 Post subject: |
|
|
| Orion9 wrote: | | она всегда будет ему известна |
Но тогда придётся макрос каждый раз редактировать )) А это неудобно.
Добавлено спустя 32 минуты:
Orion9
| болван wrote: | | избыточный бэктрекинг (откаты движка), который вызывают ленивые квантификаторы (+? и *?) |
Это существенно только при обработке гигантских массивов (гиг текста). Или для подсветок (как в AkelPad), которые в фоне постоянно шуруют. В остальных случаях речь о микродолях секунды.
| болван wrote: | | (?i)\b(button|cmd|param|path|menu|iconic)(\d++)=(.*) |
(?i) — лучше уточнить, что точка не захватывает перенос строки (?i-s), а то всякое бывает (общие настройки поменял временно и забыл).
(\d++) — одного плюса скорее всего хватит (\d+), т.к. обычно множители жадные по умолчанию (в справках об этом упоминают). В этом именно случае ++ или + большой разницы не даст, но вообще лучше не привыкать к ++, они иногда неожиданные сюрпризы подкидывают.
| болван wrote: | | Дело в том, что TRegExpr... имеет упрощенный, классический Perl-подобный синтаксис |
Не понятно, «упрощенный» по сравнению с чем? В большинстве редакторов синтаксис даже до Perl не дотягивает.
| болван wrote: | | Дело в том, что TRegExpr... В ней отсутствует поддержка сверхжадных (possessive) квантификаторов |
Неправда. Устаревшие сведения. Поддерживает, хоть и с ограничениями, но процентов 90 необходимости покрывает. И \d++ поддерживает точно.
А вообще, чем на болванов время тратить, лучше книжку Джеффри Фридла почитать. А после этого уже и с болванами работать )) _________________ Amo ergo sum |
|
| Back to top |
|
 |
Batya

Joined: 15 Dec 2004 Posts: 2235 Location: Москва, Россия
|
(Separately) Posted: Mon Jul 20, 2026 20:12 Post subject: |
|
|
| yozhik wrote: | (?m-s)^(_\|_\d+_\|_)(.+)(\1.+?)$
\1\2\r\n\3 |
Да, придётся, видимо, использовать множественный проход.
Спасибо! Завтра попробую. _________________ Нет, я не сплю. Я просто медленно моргаю. |
|
| Back to top |
|
 |
Orion9

Joined: 01 Jan 2024 Posts: 1220
|
(Separately) Posted: Tue Jul 21, 2026 12:23 Post subject: |
|
|
| yozhik wrote: | | Но тогда придётся макрос каждый раз редактировать |
А если макрос будет работать для выделенного текста?
Я не отстаиваю свой вариант, тем более, что Batya ясно дал понять, что его интересуют регулярные выражения. Но перспектива лишний раз тыкнуть на кнопку меня совершенно не пугает. Иногда это даже требуется, например, чтобы увидеть сырые данные и убедиться в правильности действий.
Кстати, не понятно, как именно располагается таблица в файле: идет ли она сплошным блоком, или фрагментирована и перемешана с другими записями? Во втором случае без скрипта не обойтись, на мой взгляд.
| yozhik wrote: | | Это существенно только при обработке гигантских массивов (гиг текста). Или для подсветок (как в AkelPad), которые в фоне постоянно шуруют. В остальных случаях речь о микродолях секунды. |
Болвана можно и об этом спросить, жалко что ль
 каков выигрыш в скорости Оптимизированное выражение работает в 3–5 раз быстрее исходного на реальных текстовых файлах.
Основной прирост скорости дает избавление движка от бэктрекинга (лишних шагов назад):
* На валидных строках (где есть совпадение) скорость возрастает примерно в 1.5–2 раза за счет того, что жадный (.*) забирает остаток строки одним махом, а не перебирает по одному символу, как ленивый (.*?).
* На неподходящих строках (где совпадения нет) скорость возрастает в 5–10 раз. Якорь ^ заставляет TRegExpr мгновенно отбрасывать строки, которые начинаются не с ключевого слова, даже не пытаясь сканировать их до конца.
В среднем на больших многострочных конфигурационных файлах (INI, LOG) общее время обработки сокращается на 70–80%.
 если выразить в секундах Чтобы дать точные цифры в секундах, я запустил бенчмарк в Python. Скрипт имитировал логику работы TRegExpr в многострочном режиме (строгая построчная проверка) на файле объемом 10 МБ (~200 000 строк), где целевые параметры встречаются в 5% случаев.
Результаты замера времени:
* Исходный вариант (?i)(button...|iconic)(\d+?)=(.*?)(\R|\Z): 1.43 сек
* Оптимизированный вариант (?mi)^(button...|iconic)(\d+)=(.*): 0.29 сек
## 📊 Чистый выигрыш в секундах
На каждые 10 МБ текста вы экономите 1.14 секунды.
Если ваш файл имеет размер 100 МБ, экономия составит уже около 11.4 секунд (общее время упадет с 14.3 до 2.9 секунд), что критично для отзывчивости интерфейса программы.
 если ini-файл 100 кб На файле размером 100 КБ (около 2 000 строк) разница в секундах будет неощутима глазом:
* Исходное выражение: 0.014 сек (14 миллисекунд)
* Оптимизированное выражение: 0.003 сек (3 миллисекунды)
## 📊 Итог
Чистый выигрыш составит около 0.011 секунды. На таком объеме данных оба варианта отработают мгновенно. Оптимизация имеет смысл только ради экономии ресурсов процессора при многократном повторении операции (например, при чтении сотен таких файлов в цикле).
| yozhik wrote: | | Не понятно, «упрощенный» по сравнению с чем? В большинстве редакторов синтаксис даже до Perl не дотягивает. |
 Болван Под «упрощенным» в данном контексте понимается сравнение с современным стандартом PCRE (Perl Compatible Regular Expressions), который сейчас используется в большинстве языков программирования (PHP, Python, R, C++) и продвинутых редакторах вроде VS Code или Sublime Text.
TRegExpr создавался очень давно и застрял на уровне базового синтаксиса Perl 5, уступая современным движкам по трем ключевым параметрам:
* Нет атомарных групп и сверхжадности: В нем отсутствуют конструкции вроде (?>...) и квантификаторы ++, *+, которые на корню убивают бэктрекинг.
* Ограниченные проверки вокруг: Проверки назад (?<=...) и (?<!...) в TRegExpr работают только с фиксированной длиной строки. Современные движки давно умеют обрабатывать там переменное количество символов.
* Бедный набор метасимволов: В библиотеке нет встроенной поддержки таких удобных шорткодов, как \R (любой перенос строки).
Вы абсолютно правы: если сравнивать TRegExpr с базовыми текстовыми редакторами (вроде стандартного Блокнота или старых IDE), его возможности кажутся огромными. Но в сравнении с современными серверными движками регулярных выражений он действительно сильно упрощен.
Вам ближе теоретические различия движков регулярных выражений или нужно решить конкретную задачу ограничения бэктрекинга в рамках TRegExpr?
| yozhik wrote: | | Неправда. Устаревшие сведения. Поддерживает, хоть и с ограничениями, но процентов 90 необходимости покрывает. И \d++ поддерживает точно. |
 Болван Вы абсолютно правы, признаю ошибку. Мои сведения действительно устарели: я упустил из виду масштабные обновления библиотеки за последние годы (начиная с крупного апдейта Алексея Торгашина и Мартина Фрибе). [1, 2]
Современный TRegExpr (который поставляется в актуальных версиях Free Pascal/Lazarus и используется в проектах вроде CudaText) действительно поддерживает сверхжадные (possessive) квантификаторы вида a++, a*+, a?+, а также атомарные группы, полноценные Lookaround-проверки и даже шорткод \R. [1, 2, 3]
Ограничение осталось разве что на сложные конструкции — например, нельзя применить сверхжадный квантификатор к группе с альтернативами в скобках вроде (foo|bar){3,5}+. Но для простых классов символов, таких как \d++, всё работает идеально и «из коробки». [3]
С учетом этого факта, самое первое оптимизированное выражение сработает в TRegExpr без каких-либо проблем:
(?mi)^(button|cmd|param|path|menu|iconic)\d++=(.*)
Вы планируете использовать сверхжадный захват \d++ для жесткого контроля откатов, или в вашем файле имена параметров гарантированно не содержат некорректных символов после цифр?
Лет 15 назад, когда Интернет по-настоящему стал набирать обороты, популярным стало выражение "не всему, что написано в Интернете, нужно верить". То же самое сейчас можно сказать и о болване. Только опытный специалист, хорошо разбирающийся в вопросе, может сразу оценить - чушь он выдает или что-то полезное. И только опытный специалист может максимально извлечь из этого пользу. Вот вы хорошо разбираетесь в регэкспресах, поэтому и можете поржать (оценить юмор) с болванистых ответов, а ведь кто-то их за чистую монету может принять
| yozhik wrote: | | лучше книжку Джеффри Фридла почитать |
Так уже, это... лежит под подушкой. Спится намного крепче и слаще  |
|
| Back to top |
|
 |
Batya

Joined: 15 Dec 2004 Posts: 2235 Location: Москва, Россия
|
(Separately) Posted: Tue Jul 21, 2026 14:54 Post subject: |
|
|
yozhik
Попробовал. Отлично! Результат меня устраивает.
(Жаль, что для изящности решения не получилось делать замену в один проход.)
Огромное спасибо!!!
Orion9
Спасибо за участие в решении и интерес к вопросу! _________________ Нет, я не сплю. Я просто медленно моргаю. |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|