RegExMatch Conundrum

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
icuurd12b42
Posts: 202
Joined: 14 Aug 2016, 04:08

RegExMatch Conundrum

20 Sep 2017, 22:17

I need to know if there is a way to find the best match from the results of multiple RegExMatch calls on the same string with different search patterns, each resulting in a match

for example

TestString:="Hello I have a problem"

RegSearch1 :="[\s\S]*" ;this finds everything
RegSearch2 := "[Hello]*" ;This finds Hello
RegSearch3 := "Hello I have a problem" ;This finds everything as exact match

Now if I perform a search using all 3 strings
RegExMatch(TestString,RegSearch1)
RegExMatch(TestString,RegSearch2)
RegExMatch(TestString,RegSearch3)
I would need to have a way to find the best match where RegSearch3 would be the best result, exact match, RegSearch2 would be the second best because it contains at least something of what I want, and RegSearch1 would be the last resort option.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: RegExMatch Conundrum

20 Sep 2017, 23:45

While !regeexmatch(str,needle[max-a_index-1],m)
icuurd12b42
Posts: 202
Joined: 14 Aug 2016, 04:08

Re: RegExMatch Conundrum

21 Sep 2017, 00:05

Hmm, tilt? It'll try to decipher this reply
icuurd12b42
Posts: 202
Joined: 14 Aug 2016, 04:08

Re: RegExMatch Conundrum

21 Sep 2017, 01:22

Hmm I give up but I found the mean to fix the core issue, which one to use first, by giving priority to the search strings...
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: RegExMatch Conundrum

21 Sep 2017, 02:03

Perhaps like this:

Code: Select all

if (vText = "Hello I have a problem")
	MsgBox, % 1
else if (vText ~= "^Hello")
	MsgBox, % 2
else
	MsgBox, % 3

;or:
if (vText = "Hello I have a problem")
	MsgBox, % 1
else if InStr(vText, "Hello")
	MsgBox, % 2
else
	MsgBox, % 3
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
icuurd12b42
Posts: 202
Joined: 14 Aug 2016, 04:08

Re: RegExMatch Conundrum

21 Sep 2017, 02:15

Thanks jeeswg but my project allows the user to enter a regex in multiple fields to filter information out of an input string and choose the right action, both the input string and the number of regex values and the regex values themselves are unknown, a hard code solution is not really the proper solution.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: RegExMatch Conundrum

21 Sep 2017, 02:16

Eg,

Code: Select all

RegSearch1 :="[\s\S]*" ;this finds everything (it doesn't)
RegSearch2 := "[Hello]*" ;This finds Hello
RegSearch3 := "Hello I have a problem" ;This finds everything as exact match

needles:=[RegSearch3,RegSearch2,RegSearch1]

msgbox % regexClosestMatch("Hello I have a problem",needles)
msgbox % regexClosestMatch("Hello I have no problems",needles)
msgbox % regexClosestMatch("Hell, I have a problem",needles)

regexClosestMatch(hay,needles){
	; needles in descending order [bestMatch,...,worstMatch]
	local m
	while !regexmatch(hay,needles[a_index],m){
	}
	return m
}
Cheers.
icuurd12b42
Posts: 202
Joined: 14 Aug 2016, 04:08

Re: RegExMatch Conundrum

21 Sep 2017, 02:28

Great stuff Helgef... try with this, as a brain puzzle if you wish since I consider this solved

msgbox % regexClosestMatch("Hello I have a problem",needles)
msgbox % regexClosestMatch("Hello I have no problems",needles)
msgbox % regexClosestMatch("I have a problem",needles) ;not found by [\s\S]*

Also I tried to make it return a Match object passing

at := regexmatch(TestString,"O)RegSearch1,oMatch)
and the only useable oMatch data was oMatch.Pos(1) and oMatch.Value(1)

oMatch.Count() returns nothing and so was pretty much everything

Finally, the point of the search is to find which of the needles is found, Not really the content in the string.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: RegExMatch Conundrum

21 Sep 2017, 04:26

Some RegEx tips.

Note: making a RegEx needle literal always comes in useful at some point.
simplest way to make a RegEx needle literal? - AutoHotkey Community
https://autohotkey.com/boards/viewtopic ... 11#p169211

Btw [\s\S]* does find everything right? Apart from CRs/LFs depending on the mode. Or not?

Code: Select all

q::
;haystack contains needle anywhere
MsgBox, % RegExMatch("Hello I have a problem", "Hello I have a problem") ;1
MsgBox, % RegExMatch("xHello I have a problemx", "Hello I have a problem") ;2

;haystack contains needle, exact match
MsgBox, % RegExMatch("Hello I have a problem", "^Hello I have a problem$") ;1
MsgBox, % RegExMatch("xHello I have a problemx", "^Hello I have a problem$") ;0

;find 0 or more consecutive characters that are e/H/l/O
MsgBox, % RegExMatch("", "[Hello]*") ;1
MsgBox, % RegExMatch("e", "[Hello]*") ;1
MsgBox, % RegExMatch("elHo", "[Hello]*") ;1
return
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
SirRFI
Posts: 404
Joined: 25 Nov 2015, 16:52

Re: RegExMatch Conundrum

21 Sep 2017, 04:55

If You want to use multiple patterns, search in order and stop when found:

Code: Select all

TestString := "Hello I have a problem"
SearchPatterns :=
(Join QC
[
	"Hello I have a problem",	;This finds everything as exact match
	"[Hello]*",	;This finds Hello
	"[\s\S]*"	;This finds everything
]
)

For ID,Pattern in SearchPatterns
{
	If (RegExMatch(TestString,Pattern))
	{
		MsgBox % "Pattern #" ID " found it."
		Break	; Stops loop
	}
}
Ps. Wouldn't .+ be better instead of [\s\S]* ?
Also, the [] means character set, so it can find something else than "Hello".
Use

Code: Select all

[/c] forum tag to share your code.
Click on [b]✔[/b] ([b][i]Accept this answer[/i][/b]) on top-right part of the post if it has answered your question / solved your problem.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: RegExMatch Conundrum

21 Sep 2017, 05:59

icuurd12b42 wrote: I tried to make it return a Match object passing
Outputting the match object is a good idea :thumbup:
m (the match object) is byref, and return is 0 if no match,

Code: Select all

regexClosestMatch(hay,needles,byref m){
	; needles in descending order [bestMatch,...,worstMatch]
	; return the first match's index in the needles array
	local i:=0
	while !regexmatch(hay,needles[++i],m){
	}
	return m?i:0
}

Code: Select all

oMatch.Pos(1)
The overall match is at oMatch.Pos(0) and it is oMatch.value(0). Note SirRFI's comments on your needles.
Btw [\s\S]* does find everything right?
I was confused, it seems it does. :wave:

Cheers.
icuurd12b42
Posts: 202
Joined: 14 Aug 2016, 04:08

Re: RegExMatch Conundrum

21 Sep 2017, 08:07

Thanks Guys, that is both enlightening and confusing at the same time :)

As I stated I resolved this at a higher lever by setting up my system with the ordering, based off the name of the treeview Item, which is IMH a better alternative for me as a dev and for the users... Basically it's what SirRFI is saying, do it in the right order and bail.

Here's the feature in my project, it will give you a better idea...

Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: RegExMatch Conundrum

21 Sep 2017, 12:56

icuurd12b42 wrote:Basically it's what SirRFI is saying, do it in the right order and bail.
That is what the function does too, but SirRFI's version is much better with the for-loop, that avoids making a call to regexmatch with blank needle if no needles matches. :oops:
Here's the feature in my project, it will give you a better idea...
I couldn't really follow what happend :? Probably I'm a bit slow, nice to see you are using your debug script though :thumbup:

Cheers.
icuurd12b42
Posts: 202
Joined: 14 Aug 2016, 04:08

Re: RegExMatch Conundrum

21 Sep 2017, 14:47

What happens is the active window is looked up in the treeview and the treeview item that is closest matching by window title, class name, control name and control text is selected

that was the regex conundrum, which of those to choose
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: RegExMatch Conundrum

21 Sep 2017, 15:30

Just thought I'd mention this in case it's useful, to get the hWnds for the active window/control:

Code: Select all

WinGet, hWnd, ID, A
ControlGetFocus, vCtlClassNN, % "ahk_id " hWnd
ControlGet, hCtl, Hwnd,, % vCtlClassNN, % "ahk_id " hWnd
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
icuurd12b42
Posts: 202
Joined: 14 Aug 2016, 04:08

Re: RegExMatch Conundrum

22 Sep 2017, 03:12

thanks I'm doing it in a roundabout way, this is much better! My way would fail if there were 2 window with the same title

Code: Select all

;control change detection
        if(hwnd == this.m_ActiveWindowhWnd)
        {
            ttl := this.m_WinActiveTitle ;get the active control name
            ControlGetFocus, OutputVar, %ttl%
            if(OutputVar != this.m_ActiveControlName) ;if changed
            {
                Debug.WriteStackPush("ProcessMonitor.OnTimer() Control Change: " . OutputVar)
                this.m_ActiveControlName := OutputVar
                ControlHwnd := this.m_ActiveControlName
                ControlGetText, OutputVar, %ControlHwnd% ;get the control text
                this.m_ActiveControlText := OutputVar
                Debug.WriteStack("------------------",2)
                Debug.WriteStack("NEW CONTROL DETECTED",2)
                Debug.WriteStack("Name: " . this.GetActiveControlName(),2)
                Debug.WriteStack("Text: " . this.GetActiveControlText(),2)
                Debug.WriteStack("------------------",2)
well maybe not but yours looks more precise.

The control hWnd will be useful as well...

as you can deduce from my code, I initially thought I was getting a ControlHwnd. a few version later I realised it was not and renamed the class variable to m_ActiveControlName, I just now renamed ControlHwnd appropriatly in the code so that there is no confusion in 3 months when I read this code again

Glad I got the ControlhWnd in there thanks again

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: inseption86 and 157 guests