1

Тема: AHK : Регулярные выражения

Здравствуйте. Столкнулся с небольшими трудностями в использовании регулярных выражений.
Я имею некий файл (chatlog.txt), в котором содержатся строки такого вида (привожу несколько строк, дабы было понятно их различие):

[10:57:16] Объявление на проверку: ищу Augusto Bottichelli, От: Kano Holmes [478]
[11:04:36] Интерн Александор Форгинский:  кто может провести экз
[11:35:42] {1e90ff}Вы вылечили {FFFF00}Cambio Mephistos{1e90ff} за {34c924}$25

Мне нужно из всех строк найти строку, которая обязательно будет содержать в себе:

{1e90ff}Вы вылечили 

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

SendInput, {F8}

Надеюсь на Вашу помочь, зараннее спасибо.

2 (изменено: Botsy, 2021-01-18 22:31:36)

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

v413ry4nk4 Не понятно, что куда кого. Есть файл -> ищем совпадение -> если есть, то отправляем. Наверно так.


FileRead, var, chatlog.txt
if RegExMatch(var, "\{[a-z0-9]{6}\}+[ёЁА-Яа-я\s]{11}")
SendInput, {F8}
GD

3

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

Botsy Ваш пример конкретно под нужную мне строку или в общем виде?

4 (изменено: Botsy, 2021-01-18 22:08:11)

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

v413ry4nk4 Общий вид {000000}аа аааааааа .

GD

5

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

var := "{000000}ёа аааааааа"
msgbox % RegExMatch(var, "\{[a-z0-9]{6}\}+[А-Яа-я\s]{11}")

6 (изменено: Botsy, 2021-01-18 22:31:18)

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

Malcev Букву "ё" не ловит, ее надо как-то по особенному добавлять ?

Upd: оказалось нужно явно ее добавлять. Спасибо.

GD

7

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

Зачем так явно, если как я понимаю ожидается любой текст.


var = 
(
[10:57:16] Объявление на проверку: ищу Augusto Bottichelli, От: Kano Holmes [478]
[11:04:36] Интерн Александор Форгинский:  кто может провести экз
[11:35:42] {1e90ff}вы вылечили {FFFF00}Cambio Mephistos{1e90ff} за {34c924}$25
)
If RegExMatch(var, "(*UCP)\{[a-f0-9]{6}\}\s*([\w\s]+?)\s*\{", m)
&& m1 ~= "i)^Вы вылечили$"
	MsgBox вылечили
Return
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
Win10x64 v20H2, AutoHotkey_L v1.1.33.09 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

8

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

А если по ТЗ, то RegEx тут ни при чём.


var = 
(
[10:57:16] Объявление на проверку: ищу Augusto Bottichelli, От: Kano Holmes [478]
[11:04:36] Интерн Александор Форгинский:  кто может провести экз
[11:35:42] {1e90ff}Вы вылечили {FFFF00}Cambio Mephistos{1e90ff} за {34c924}$25
)

If InStr(var, "{1e90ff}Вы вылечили ")
	MsgBox вылечили
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
Win10x64 v20H2, AutoHotkey_L v1.1.33.09 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

9 (изменено: Botsy, 2021-01-19 13:57:01)

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

serzh82saratov Это наверное более грамотно, но я даже не понимаю что вы написали в regexmatch.

GD

10

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

serzh82saratov Можете объяснить свой ответ?

(*UCP) - всегда используем для повышения производительности в регулярных выражениях
\{[a-f0-9]{6}\}\s*([\w\s]+?)\s*\{", m) - регулярный шаблон для множества строк. А зачем в конце это "\{" ?
&& m1 ~= "i)^Вы вылечили$ - это что-то типо, либо ищем регулярный шаблон до знака &&, либо после знака ? Почему тут используется m1, i)^ ?

GD

11

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

Botsy пишет:

(*UCP) - всегда используем для повышения производительности в регулярных выражениях

Откуда вы это взяли? Это про юникод, и это наоборот замедляет.

Botsy пишет:

А зачем в конце это "\{" ?

Поиск до "{", я это сделал чтобы не захватывать пробелы в конце (не знаю как это сделать иначе), ведь они могут быть и в составе строки.

Botsy пишет:

&& m1 ~= "i)^Вы вылечили$ - это что-то типо, либо ищем регулярный шаблон до знака &&, либо после знака

Нет, это после RegExMatch проверяет найденное на полное соответствие указанной строке в любом регистре.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
Win10x64 v20H2, AutoHotkey_L v1.1.33.09 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

12

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

serzh82saratov Про UCP прочитал в справке:

(*UCP) Используется для повышения производительности \ d, \ D, \ s, \ S, \ w, \ W, \ b и \ B по умолчанию распознают только символы ASCII, даже в кодировке Unicode. Если шаблон начинается с (* UCP), свойства Unicode будут использоваться для определения совпадающих символов. Например, \ w становится эквивалентным [\ p {L} \ p {N} _], а \ d становится эквивалентным \ p {Nd}.
Не знаю что за шаблон [\ p {L} \ p {N} _], но подумал про ускорение работы из-за замены совпадений.

Нет, это после RegExMatch проверяет найденное на полное соответствие указанной строке в любом регистре.

Мы в переменной ищем совпадение согласно заданному рег. шаблону и если мы такое нашли, зачем нам проверять это на полное соответствие? Просто выглядит противоречиво: сначала мы ищем согласно общему шаблону, а потом на 100% совпадение. Не легче ли изначально тогда искать по шаблону {динамический цвет} + вы вылечили ?
Ну а если поиск всегда статический, то получается надо использовать ваш второй вариант с InStr.

GD

13

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

Botsy пишет:

Используется для повышения производительности

Я имел ввиду производительность падает в сравнении с поиском ANSI, то есть без (*UCP).

Botsy пишет:

выглядит противоречиво: сначала мы ищем согласно общему шаблону, а потом на 100% совпадение

По ТЗ нужен только InStr, пример с RegEx, это про то когда есть несколько вариантов строки, сначала один раз определяем что в ней, а далее просто сравниваем со своими вариантами.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
Win10x64 v20H2, AutoHotkey_L v1.1.33.09 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

14

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

serzh82saratov Понял.

GD

15 (изменено: v413ry4nk4, 2021-01-19 17:49:47)

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

serzh82saratov, сейчас проверил 2 ваших варианта. На удивление, вариант с

If InStr(var, "{1e90ff}Вы вылечили ")

ни в какую не хочет работать, а вот с использованием

If RegExMatch(var, "(*UCP)\{[a-f0-9]{6}\}\s*([\w\s]+?)\s*\{", m)
&& m1 ~= "i)^Вы вылечили$"

частично заработал. Сейчас объясню, почему частично.
У меня имеются строки такого вида:

$Numpad4::
	IniRead, num4_1, actions.ini, Адреналин, num4_1
	Sleep 100
	{
		SendChat(num4_1)
	}
	Sleep 100
	{
		AutoHeal_25()
	}
	Sleep 500
	{
		AutoScreen()
	}
	Return

где

AutoScreen() {
	ChatLog = C:\Users\%A_UserName%\Documents\GTA San Andreas User Files\SAMP\chatlog.txt
	Loop, {
	var := GetNewLine(ChatLog)
	
	If RegExMatch(var, "(*UCP)\{[a-f0-9]{6}\}\s*([\w\s]+?)\s*\{", m)
	&& m1 ~= "i)^Вы вылечили$"
		{
    		SendChat("/время")
    		Sleep 100
    		SendInput, {F8}
		}
	}
	Return
}

Я решил реализовать это с помощью функции, но она выполняется единожды. При повторном вызове Numpad4 скрипт не реагирует, как будто клавиша и не назначена хоткеем. Таких хоткеев у меня 52, и в каждом должна выполнятся эта функция. На всех она срабатывает единожды. Как можно это решить? Мне нужно, чтобы после выполнения кода на Numpad4 либо любой-другой хоткей он оставался рабочим и я мог повторно вызвать этот код. Зараннее спасибо.

16

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

v413ry4nk4 пишет:

ни в какую не хочет работать

Что нибудь с кодировкой файла.

v413ry4nk4 пишет:

с помощью функции, но она выполняется единожды

У вас Loop не завершается.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
Win10x64 v20H2, AutoHotkey_L v1.1.33.09 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

17 (изменено: v413ry4nk4, 2021-01-19 19:52:24)

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

serzh82saratov

serzh82saratov пишет:

Что нибудь с кодировкой файла.

Да, после сохранения в UTF8+BOM

If InStr(var, "{1e90ff}Вы вылечили ")

заработал.
По поводу завершения цикла, я попробовал завершить его командой Break,

AutoScreen() {
    ChatLog = C:\Users\%A_UserName%\Documents\GTA San Andreas User Files\SAMP\chatlog.txt
    Loop, {
    var := GetNewLine(ChatLog)
    
    If InStr(var, "{1e90ff}Вы вылечили ")
        {
            SendChat("/время")
            Sleep 100
            SendInput, {F8}
        }
    Break
    }
}

Но по итогу функция выполняется только один раз, хотя хоткей уже не блокируется. Т.е. хоткей выполняется повторно, но функция  AutoScreen уже не срабатывает,  не посылает нажатие F8. В чём может быть проблема?
P.S: добавление Return перед последней  } ситуации не меняет.

18

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

v413ry4nk4 пишет:

только один раз

А как ещё, если Break сразу применять.
Его надо вызвать на последней строке, или когда вам там надо.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
Win10x64 v20H2, AutoHotkey_L v1.1.33.09 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

19

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

serzh82saratov пишет:

Его надо вызвать на последней строке

Но я же его и вызываю на последней строке цикла, разве не так?

20

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

На последней строке ChatLog.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
Win10x64 v20H2, AutoHotkey_L v1.1.33.09 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

21 (изменено: v413ry4nk4, 2021-01-19 20:13:06)

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

serzh82saratov пишет:

На последней строке ChatLog.

ChatLog ведь за пределами цикла, он в самом начале функции, или я что-то совсем не понимаю?

AutoScreen() {
    ChatLog = C:\Users\%A_UserName%\Documents\GTA San Andreas User Files\SAMP\chatlog.txt
    Loop, {
    var := GetNewLine(ChatLog)
    
    If InStr(var, "{1e90ff}Вы вылечили ")
        {
            SendChat("/время")
            Sleep 100
            SendInput, {F8}
        }
    Break
    }
}

Break у меня перед закрывающей } в цикле, это должно быть как-то иначе?

22

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

Я думал цикл перебирает по одной строке, если не так (зачем тогда там цикл), то это надо весь код смотреть.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
Win10x64 v20H2, AutoHotkey_L v1.1.33.09 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

23

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

serzh82saratov, сейчас постараюсь объяснить.
У меня имеется функция GetNewLine()

GetNewLine(filename) {
    static old
    static new

    if !old {
        FileGetSize, old, %filename%
        new := old
    }

    while old = new {
        sleep 100 ;задержка
        FileGetSize, new, %filename%
    }

    old := new
    Loop, read, %filename%
    if A_LoopReadLine {
            last := A_LoopReadLine
    }
    return last
}

Писал я её не сам, брал готовую. Каждые 100мс сравнивается размер файла chatlog.txt, и если в нём обнаружены изменения - то последняя строка присваивается переменной.
Далее в функции AutoScreen()

AutoScreen() {
    ChatLog = C:\Users\%A_UserName%\Documents\GTA San Andreas User Files\SAMP\chatlog.txt
    
    Loop,
    { 
        var := GetNewLine(ChatLog)
        If InStr(var, "{1e90ff}Вы вылечили ")
            {
                SendChat("/время")
                Sleep 100
                SendInput, {F8}
            }
        Break
    }
}

Эта строка проверяется на наличие {1e90ff}Вы вылечили , и если это так - то выполняется

{
	SendChat("/время")
	Sleep 100
	SendInput, {F8}
}

Возможно я изначально действовал неправильно, и можно как-то объединить GetNewLine() и AutoScreen() в одну функцию?

24 (изменено: v413ry4nk4, 2021-01-19 20:38:48)

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

serzh82saratov пишет:

(зачем тогда там цикл)

Мне нужно после нажатия определенного хоткея, который вызывает функцию AutoScreen() ждать до момента обнаружения {1e90ff}Вы вылечили ,
а кроме использования цикла для непрерывной проверки мне ничего больше в голову не пришло.

25

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

Тут надо всё переписывать, а вы далеко отошли от темы.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
Win10x64 v20H2, AutoHotkey_L v1.1.33.09 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

26

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

serzh82saratov пишет:

Тут надо всё переписывать

Этот ответ меня впринципе удовлетворит, Вы дали понять, что ошибка была допущена в самом начале, буду искать.

serzh82saratov пишет:

а вы далеко отошли от темы.

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

Спасибо всем, кто откликнулся, за помощь.