Регулярные выражения

Russian main discussion
  • Author
  • Message
Offline
Posts: 348
Joined: Mon Jun 03, 2019 2:33 am

Post by AZJIO »

InFive
Сделать то можно, но кто возьмётся за эту задачу, кому она нужна?
Можно и без TextReplace.js. То есть в самой поисковой строке изначально искать нужное, а в регулярном выражении в качестве замену указать функцию, которая обработает данные, вот тут то функция может числа отправить в массив, прибавить 1 и снова собрать с заданным разделителем и заменить в итоговом результате. Осталось найти человека, который это сделает.

Offline
Posts: 11
Joined: Mon Apr 07, 2008 1:28 am

Post by AkelPadUser »

Подскажите.
Вот есть например текст смс баланса по картам: блаблабла МИР3333 баланс 333, блаблаабла МИР5555 баланс 555 блаблабла. Подскажите, как мне извлечь сумму баланса МИР5555? Какое выражение надо?

===========================
opk44 - спасибо!
Last edited by AkelPadUser on Fri May 21, 2021 7:44 pm, edited 1 time in total.

Offline
Posts: 874
Joined: Sat Jan 16, 2010 2:03 pm

Post by opk44 »

AkelPadUser
Если баланс всегда целое число, то

Code: Select all

(?<=МИР5555 баланс )(\d+)
Если баланс м.б. с копейками, а разделитель - точка, то

Code: Select all

(?s)(?<=МИР5555 баланс )(\d+.\d+)

Offline
Posts: 874
Joined: Sat Jan 16, 2010 2:03 pm

Пример использования negative lookahead

Post by opk44 »

Пример использования "Отрицательного поиска вперед" (negative lookahead) с пояснениями "для гуманитариев".


Есть отличный скрипт "LinesFilter.js", призванный фильтровать строки, используя регулярные выражения.
Вкратце, скрипт позволяет работать в двух режимах фильтра:
1) Оставить строки, содержащие заданный образец;
2) Удалить строки, содержащие заданный образец.

Вопрос/Задача: Можно ли сделать это же с помощью одних только регулярных выражений и как?

Заглянем внутрь скрипта.
Код поиска паттерна (образца/шаблона) находится в строке 516:
oPattern=new RegExp((bAtLineStart?"":"^.*") + "(" + (bRegExp?pFindIt:EscRegExp(pFindIt)) + ")" + (bAtLineEnd?"":".*$") + "\n?", "gm" + (bSensitive?"":"i"));
Что тут происходит? В серединке введённый паттерн преобразуется к формату JScript. А по краям приклеиваются префикс "^.*" и суффикс ".*$\n?", обеспечивающие захват полной строки ("с начала строки" + "паттерн" + "до конца строки" + "конец строки"). Плюс дополнительные опции (регистрозависимость).

Таким образом решение ВТОРОЙ части задачи "- Удалить строки, содержащие заданный образец" является очень простым. Достаточно "украсть" данное выражение и заменять в диалоге "Замена" на пустой образец:

Что:

Code: Select all

(?-s)^.*(здесь ваш образец).*$\n?
Чем: _оставить пустым_
Опции: [v] Регулярные выражения

Теперь о том, как решить ПЕРВУЮ часть задачи.
"Оставить строки, содержащие заданный образец" равнозначно выражению "Удалить строки, НЕ содержащие заданный образец"
И тут на помощь приходит negative lookahead:
(?!шаблон) -- Отрицательный поиск вперед (negative lookahead). Соответствие не сохраняется для последующего использования. Например, 'Windows (?!95|98|NT|2000)' соответствует "Windows" в "Windows 3.1", но не соответствует "Windows" в "Windows 2000".
Что:

Code: Select all

(?-s)^((?!здесь ваш образец).)*$\n?
Чем: _оставить пустым_
Опции: [v] Регулярные выражения

===
P.S. Пояснение для "гуманитариев". Документация по регулярным выражениям в AkelPad занимает всего около двух страниц. Это конспект, а не учебник, и поэтому она не может являться исчерпывающим пособием по регулярным выражениям. Для сравнения, "специальная литература" по данному вопросу "в простом варианте" - это страниц 175, а в "углублённом" - около 600. Поэтому, если вам "непонятны" те или иные слова/термины в документации, то просто берите их "на карандаш" и обращайтесь к специальной литературе (ленивые - к Википедии). Ждать, "когда исправят документацию?"* бессмысленно (*ответ: "никогда").
Litterarum radices amarae, fructus dulces sunt. В переводе означает, что потраченное на "непонятные слова" время окупится раньше, чем многим кажется.

Offline
Posts: 3234
Joined: Wed Nov 29, 2006 1:19 pm
Location: Киев, Русь
Contact:

Post by VladSh »

Приветствую, ребята!
С регулярками всегда мне было сложно, а сейчас что-то вообще туплю...
Перепилил скрипт для tidy, и вот хочу доделать анализ на игнорируемые типы, чтобы лишними сообщениями нас (пользователей) не задалбывать.

Задача: определить, есть ли в передаваемом тексте хоть одна строка, содержащая в начале текст "Info: " и НЕ содержащая "UNKNOWN_ENTITY" или "MISSING_ATTRIBUTE".
Получилось только найти когда строки содержат эти вхождения, а нужно отрицание.

Code: Select all

//var str = 'Info: messages of type "UNKNOWN_ENTITY" will not be output (STRING_MUTING_TYPE)';
var str = 'Info: messages of type "MISSING_ATTRIBUTE" will not be output (STRING_MUTING_TYPE)';
var re = new RegExp(/^Info: .*^UNKNOWN_ENTITY|MISSING_ATTRIBUTE.*/);
var res = re.test(str);
AkelPad.Call("Log::Output", 4, "" + res, -1, 0);
И в идеале конечно хотелось бы, чтобы поиск шёл с конца текста, т.к. Info-сообщения идут снизу.

Что-то вот такое у меня сейчас написано, только с паттерном никак не разберусь:

Code: Select all

// Производит проверку соответствия строк паттерну pattern снизу вверх;
// останавливается сразу, как только строка не соответсвует паттерну.
// Возвращает индекс начала нижней подходящей строки либо -1.
//   Передавать text без пустых строк снизу!
function lastIndexOf(text, pattern) {
	var re = new RegExp(pattern);
	var nb;
	var ne = text.length;
	do {
		nb = text.lastIndexOf("\r", ne);
		if (!re.test(text.slice(nb + 1, ne)))
			return (ne != text.length) ? ne + 2 : -1;
		else
			if (nb == -1) return 0;
		ne = nb - 1;
	}
	while (true);
}

Offline
Posts: 40
Joined: Thu May 05, 2022 5:38 am

Post by dothen »

VladSh wrote:Задача: определить, есть ли в передаваемом тексте хоть одна строка, содержащая в начале текст "Info: " и НЕ содержащая "UNKNOWN_ENTITY" или "MISSING_ATTRIBUTE".

Code: Select all

/^Info: (?!.*(UNKNOWN_ENTITY|MISSING_ATTRIBUTE))/    //Соответствует "Info: "
/^Info: (?!.*(UNKNOWN_ENTITY|MISSING_ATTRIBUTE)).*/    //Соответствует всей строке
Для re.test без разницы.

Offline
Posts: 3234
Joined: Wed Nov 29, 2006 1:19 pm
Location: Киев, Русь
Contact:

Post by VladSh »

dothen
Спасибо!

DV
Offline
Posts: 1291
Joined: Thu Nov 16, 2006 11:53 am
Location: Kyiv, Ukraine

Re: Регулярные выражения

Post by DV »

Why

Code: Select all

[^\x00-\x7F]
matches new-line (end-of-line) symbols?
I mean, CR as \x0D and LF as \x0A are within the range \x00-\x7F, so they should be excluded according to [^\x00-\x7F].

Offline
Posts: 29
Joined: Tue Jun 30, 2020 11:33 am

Re: Регулярные выражения

Post by random6_2020 »

DV wrote: Tue Sep 26, 2023 8:33 amI mean, CR as \x0D and LF as \x0A are within the range \x00-\x7F, so they should be excluded according to [^\x00-\x7F].
See this topic: https://akelpad.sourceforge.net/forum/v ... php?t=1936
AkelPad uses unconventional internal representation of newlines. So the correct regexp in this case should mention newline directly:

Code: Select all

 [^\x00-\x7F\r\n]

Offline
Posts: 348
Joined: Mon Jun 03, 2019 2:33 am

Re: Регулярные выражения

Post by AZJIO »

В теме регулярных выражений на руборде поднялась тема движка в AkelPad. Используется ли PCRE или что-то другое? Последняя ли версия. По описанию в AkelHelp-Rus.htm я не вижу разницы между PCRE, кроме некоторых моментов.
1. Не работает рекурсия A(?R)?Z для текста AAAZZZ, шаблон выдаёт ошибку в регвыр.
2. Не поддерживается метасимвол \h использую [ \t] в качестве замены. И не выдаёт ошибки, воспринимая как литерал, находит "h" в тексте.
3. Не работает ссылка на группы ^([ ]{4})|(?1) то есть ошибка в (?1)
4. ^[ ]{2}|(?<=^[ ]{2})[ ]{2}|(?<=^[ ]{4})[ ]{2} - выдаёт ошибку использования {2} в (?<=...)
5. Нет описания что в поле замены обрабатываются метасимволы \t или \x20. Это поле обрабатывается Escape-последовательностями?

Если взять скрипт FindReplaceEx.js то тут можно встретить игнор \r, то есть если бы в обычных регвырах перенос строки CRLF в регвырах используется как \r\n то тут это просто \n.

В SearchReplace.js очень многое не работает.

Offline
Posts: 1873
Joined: Mon Aug 06, 2007 1:07 pm
Contact:

Re: Регулярные выражения

Post by Infocatcher »

AZJIO wrote: Mon Sep 16, 2024 8:03 am В теме регулярных выражений на руборде поднялась тема движка в AkelPad. Используется ли PCRE или что-то другое?

В SearchReplace.js очень многое не работает.
Где-то тут уже писали, что в AkelPad своя реализация движка регулярных выражений.

В SearchReplace.js регулярные выражения, реализованные в системном движке JScript. И он, к сожалению, еще и не новый – вроде как, ничего в нем не обновляется, браузер нынче отдельно, Windows Script Host отдельно.

Offline
Posts: 29
Joined: Tue Jun 30, 2020 11:33 am

Re: Регулярные выражения

Post by random6_2020 »

AZJIO wrote: Mon Sep 16, 2024 8:03 am 3. Не работает ссылка на группы ^([ ]{4})|(?1) то есть ошибка в (?1)
Ссылка на группы это \#. Так работает, например: ^( {4})===\1aa
AZJIO wrote: Mon Sep 16, 2024 8:03 am 4. ^[ ]{2}|(?<=^[ ]{2})[ ]{2}|(?<=^[ ]{4})[ ]{2} - выдаёт ошибку использования {2} в (?<=...)
Видимо баг, т.к. так работает: (?<= ) {2} а так - нет: (?<= {1}) {2}
AZJIO wrote: Mon Sep 16, 2024 8:03 am в поле замены обрабатываются метасимволы \t или \x20. Это поле обрабатывается Escape-последовательностями?
В режиме регэкспов и эскейпов - да.
Post Reply