Тема: AHK: Вопросы по RegExp [, RegEx, RegExMatch, RegExReplace]
Я искал такую тему (считаю, что она вообще должна быть закреплена в этом разделе или хотя ссылка на неё должна быть в правилах раздела), но не нашёл: если она уже существует - модератор может убить эту тему приклеив из неё сообщение в новую тему (если это невозможно - то сначала дайте мне ссылку на неё, там я продублирую свой вопрос, а эту тему можно будет просто удалить).
У меня возникли трудности при составлении сложного шаблона регулярных выражений для команды RegExMatch.
См. строку №5:
For Process In ComObjGet("winmgmts:").ExecQuery("Select * from Win32_Process")
{
input = "c:\path.ahk\folder\noteven.ahk.exe" "c:\fake\parameter\with\path\to.ahk" ; эта и следующая строки используются в тестовых целях: с их помощью можно подделать реально обрабатываемый Process.CommandLine каким-то значением.
Process.CommandLine := input ; приходится использовать временную переменную input, т.к. нельзя просто взять и назначить Process.CommandLine'у значение через знак равенства, а если назначать через := - то нужно вручную "экранировать" кавычки.
If RegExMatch(Process.CommandLine, "[^\\]+\.ahk(?=\W*)", tempVar)
Msgbox %A_Index%: |%tempVar%|
Else
Msgbox the input didn't pass the regexmatch!
}
; Примеры 1-4 должны проходить RegExMatch, примеры 5-6 - не должны. Во всех примерах добавлены пайпы по краям в качестве разделителей: просто чтобы можно было заметить на конце пробел после кавычки в примере №4. Сами пайпы не являются частью тестируемого input'а.
;
; Примеры:
; |"C:\Program Files\AutoHotkey\AutoHotkey.exe" /restart "C:\Program Files\AutoHotkey\Scripts\In Development\DrugWinManager (with GDI+ pin).ahk"|
; |"C:\Program Files\AutoHotkey\AutoHotkey.exe" "C:\Program Files\AutoHotkey\Scripts\In Development\Remap ALT+F4 to CTRL+W.ahk"|
; |"C:\Program Files\AutoHotkey\AutoHotkey.exe" "C:\Program Files\AutoHotkey\Scripts\In Development\PerAppVolCtrl\PerAppVolumeControl.ahk"|
; |"C:\Program Files\AutoHotkey\AutoHotkey.exe" "C:\Users\Администратор\Desktop\puewtest.ahk" |
; |"C:\Path\to\evil\virus.exe" "C:\this\is a\fake parameter\to bypass the regexp.ahk"|
; |"C:\Path\to\evil\virus.exe" "C:\Program files\Autohotkey.exe" "C:\all parameters\are fake and just get ignored by virus.exe\to bypass the regexp.ahk"|
Проблема в том, что шаблон должен обрабатывать любую строку на входе так, что:
1. если она не является commandline'ом живого процесса ahk-скрипта - то она не должна подпадать под regexmatch шаблон (т.е. в tempvar записывается 0)
2. если шаблон распознаёт, что на входе у него commandline живого процесса ahk-скрипта, то он должен преобразовать его просто в имя этого скрипта: без пути к файлу скрипта, без каких-либо лишних символов (кавычек, пробелов, параметров запуска скрипта (например, /restart).
Сейчас у мой RegExMatch так составлен, что он хорошо справляется со 2-ым требованием, но не справляется с первым: он не умеет отличать процесс ahk от virus.exe запущенного с путём к .ahk как параметром командной строки.
Чтобы решить эту проблему - можно, конечно, использовать дополнительную проверку, но хотелось бы обойтись одним RegExMatch.
If (Process.ExecutablePath == A_AhkPath) ; Свойство ExecutablePath содержит в себе только путь к исполняемому файлу процесса, так что это надёжная проверка.
Process.CommandLine := RegExReplace(Process.CommandLine, "i)^.*\\|\.ahk\W*") . ".ahk"
Чтобы научить его отличать процессы ahk - нужно проверять на наличие в input'е содержимого переменной A_AhkPath, но так хитро, чтобы последний из примеров не проходил RegExMatch (т.к. там процесс всё-таки virus.exe)
И отдельная проблема это возможное наличие /restart между путём к ahk и путём к самому скрипту (см. пример №1).
Edit: serzh82saratov решил мою проблему, написав грамотный и сложный RegEx шаблон:
If RegExMatch(Process.CommandLine, "^(""|\s)*\Q" A_AhkPath "i)\E.*\\(?<Name>.*\.ahk)(""|\s)*$", Script)