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.
RegExMatch Conundrum
-
- Posts: 202
- Joined: 14 Aug 2016, 04:08
Re: RegExMatch Conundrum
While !regeexmatch(str,needle[max-a_index-1],m)
-
- Posts: 202
- Joined: 14 Aug 2016, 04:08
Re: RegExMatch Conundrum
Hmm, tilt? It'll try to decipher this reply
-
- Posts: 202
- Joined: 14 Aug 2016, 04:08
Re: RegExMatch Conundrum
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...
Re: RegExMatch Conundrum
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
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
-
- Posts: 202
- Joined: 14 Aug 2016, 04:08
Re: RegExMatch Conundrum
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.
Re: RegExMatch Conundrum
Eg,
Cheers.
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
}
-
- Posts: 202
- Joined: 14 Aug 2016, 04:08
Re: RegExMatch Conundrum
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.
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.
Re: RegExMatch Conundrum
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?
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
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Re: RegExMatch Conundrum
If You want to use multiple patterns, search in order and stop when found:
Ps. Wouldn't .+ be better instead of [\s\S]* ?
Also, the [] means character set, so it can find something else than "Hello".
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
}
}
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.
Re: RegExMatch Conundrum
Outputting the match object is a good ideaicuurd12b42 wrote: I tried to make it return a Match object passing
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
}
The overall match is at oMatch.Pos(0) and it is oMatch.value(0). Note SirRFI's comments on your needles.Code: Select all
oMatch.Pos(1)
I was confused, it seems it does.Btw [\s\S]* does find everything right?
Cheers.
-
- Posts: 202
- Joined: 14 Aug 2016, 04:08
Re: RegExMatch Conundrum
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...
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...
Re: RegExMatch Conundrum
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.icuurd12b42 wrote:Basically it's what SirRFI is saying, do it in the right order and bail.
I couldn't really follow what happend Probably I'm a bit slow, nice to see you are using your debug script thoughHere's the feature in my project, it will give you a better idea...
Cheers.
-
- Posts: 202
- Joined: 14 Aug 2016, 04:08
Re: RegExMatch Conundrum
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
that was the regex conundrum, which of those to choose
Re: RegExMatch Conundrum
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
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
-
- Posts: 202
- Joined: 14 Aug 2016, 04:08
Re: RegExMatch Conundrum
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
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
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)
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
Who is online
Users browsing this forum: inseption86 and 157 guests