AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Re: RegExMatch, Why is it not finding all the subpatterns?

 
Reply to topic    AutoHotkey Community Forum Index -> Ask for Help
View previous topic :: View next topic  
Author Message
Larry



Joined: 03 Mar 2005
Posts: 61

PostPosted: Sat Mar 20, 2010 5:12 pm    Post subject: Re: RegExMatch, Why is it not finding all the subpatterns? Reply with quote

I'm trying to use "RegExMatch" to return every set of
consecutive numbers in my test string.

Here is my test script:
Code:
test := "ab1.1 22 33 44 55 66 77 88 99 0.0yz"

RegExMatch(test, "[\d\.]+", match)

str := "match = " . match . "`n"
Loop, 10
 str .= "match" . A_Index . " = " . match%A_Index% . "`n"

msgbox,,, %str%, 5
return


Using the test string and my Regular Expression in
RegexBuddy, it finds exactly what I am looking for, which is:
1.1
22
33
44
55
66
77
88
99
0.0

According to the Ahk Documentation on RegExMatch:
"Matches are stored in an array using the base name
provided for the OutputVar (which in my script is "match");
and the matching substring patterns would then be stored
in the array variables match1, match2, match3, etc..

But, when I take the Regular Expression I used in RegexBuddy
and use it in my script with RegExMatch, this is all I get:
match = 1.1
match1 =
match2 =
match3 =
match4 =
match5 =
match6 =
match7 =
match8 =
match9 =
match10 =

As you can see, my script finds only the first Match
and all the array variables remain empty.

I'm just a Regular Expression novice trying hard to
learn the language, and I've already spent more than
eight hours working on this one problem.

Please anyone.... What am I missing here?
Back to top
View user's profile Send private message
jaco0646



Joined: 07 Oct 2006
Posts: 3113
Location: MN, USA

PostPosted: Sat Mar 20, 2010 5:28 pm    Post subject: Reply with quote

RegExMatch is not global. It fills an array only "If any capturing subpatterns are present..."

For global matching you need something like grep(). You may also just use RegExMatch in a loop.
Code:
test = ab1.1 22 33 44 55 66 77 88 99 0.0yz

pos = 1
While pos := RegExMatch(test,"[\d\.]+", match, pos+StrLen(match))
 MsgBox,% match
Back to top
View user's profile Send private message Visit poster's website
sinkfaze



Joined: 18 Mar 2008
Posts: 5044
Location: the tunnel(?=light)

PostPosted: Sat Mar 20, 2010 5:33 pm    Post subject: Reply with quote

You're not capturing subpatterns because you didn't specify any to capture. Parenthesis () specify subpatterns:

Code:
var := "The quick brown fox jumps over the lazy dog."
RegExMatch(var,"brown (fox)",match)
MsgBox %match%
MsgBox %match1%


In this case you don't really need to specify subpatterns, you just need a find a way to keep the matching moving through the entire string, which is where a While loop comes in:

Code:
test := "ab1.1 22 33 44 55 66 77 88 99 0.0yz"

Pos=1
While Pos :=    RegExMatch(test, "[\d\.]+", m,Pos+StrLen(m))
   str .= ((A_Index=1) ? "" : "`n") "Match #" A_Index " = " m
msgbox, %str%
return


EDIT: jaco beat me to it. Very Happy
_________________
Try Quick Search for Autohotkey or see the tutorial for newbies.
Back to top
View user's profile Send private message Send e-mail
Larry



Joined: 03 Mar 2005
Posts: 61

PostPosted: Sat Mar 20, 2010 9:40 pm    Post subject: Thank you to both sinkfaze and jaco0646 Reply with quote

Thanks guys, the "while" loop was the answer.

I think the ahk documentation is very misleading as it makes no mention of the fact that a "while" loop is needed to build the RegExMatch arrays.

Since RegexBuddy needed no such assistance from a loop to grab all the subpatterns when I tested my Regular Expression, I was clearly lead astray.
Back to top
View user's profile Send private message
MasterFocus



Joined: 08 Apr 2009
Posts: 3035
Location: Rio de Janeiro - RJ - Brasil

PostPosted: Sun Mar 21, 2010 2:48 am    Post subject: Re: Thank you to both sinkfaze and jaco0646 Reply with quote

Larry wrote:
a "while" loop is needed to build the RegExMatch arrays.

It is not. You're not even capturing subpatterns, as sinkfaze explained.
_________________
"Read the manual. Read it again. Search the forum.
Try something before asking. Show what you've tried.
"

Antonio França
My stuff: Google Profile
Back to top
View user's profile Send private message Visit poster's website
jaco0646



Joined: 07 Oct 2006
Posts: 3113
Location: MN, USA

PostPosted: Sun Mar 21, 2010 3:29 am    Post subject: Reply with quote

To be fair, RegExMatch does not claim to work with RegExBuddy, which I would guess is similar to RegExr in that it has a global option that is on by default. Note that global is an option, not an inherent feature of regular expressions. AHK simply has a different default setting than you're used to.
AHK Help File wrote:
If any capturing subpatterns are present... their matches are stored in an array
This seems clear that without subpatterns there is no array. Could you suggest an alternate description?
Back to top
View user's profile Send private message Visit poster's website
jethrow



Joined: 24 May 2009
Posts: 1907
Location: Iowa, USA

PostPosted: Sun Mar 21, 2010 4:27 am    Post subject: Reply with quote

Larry wrote:
... a "while" loop is needed to build the RegExMatch arrays.
Here's an alternate option, if you want to use AutoHotkey_L:
Code:
test := "ab1.1 22 33 44 55 66 77 88 99 0.0yz"

RegExMatch( test, "[\d\.]+(?CFunc)" )
MsgBox, %str%

Func( m ) {
   global pos, str, n := (!n ? 1 : n)
   If ( NumGet(A_EventInfo, 24, "Int") > pos ) ; if the "current match pos" > "the previous match pos"
      str .= "Match #" n++ " = " m "`n"
      , pos := NumGet(A_EventInfo, 24, "Int") ; save "current match pos"
   Return 1
}

Or, I suppose RegExReplace would work easier here:
Code:
test := "ab1.1 22 33 44 55 66 77 88 99 0.0yz"

RegExReplace( test, "[\d\.]+(?CFunc)" )
MsgBox, %str%

Func( m ) {
   global str, n := (!n ? 1 : n)
   str .= "Match #" n++ " = " m "`n"
}

_________________
Very Happy - in case I forgot to smile
Basic Webpage Controls
COM Object Reference
Back to top
View user's profile Send private message Visit poster's website Yahoo Messenger
sinkfaze



Joined: 18 Mar 2008
Posts: 5044
Location: the tunnel(?=light)

PostPosted: Sun Mar 21, 2010 6:18 am    Post subject: Re: Thank you to both sinkfaze and jaco0646 Reply with quote

Larry wrote:
I think the ahk documentation is very misleading as it makes no mention of the fact that a "while" loop is needed to build the RegExMatch arrays.


A while loop is not needed to build the RegExMatch array, your matching was not designed to require the array. This example returns an array created by RegExMatch:

Code:
test := "the quick brown fox jumps over the lazy dog"
RegExMatch(test,"^(\w+) (\w+) (\w+) (\w+)",m)
MsgBox % m
Loop, 4
   MsgBox % m%A_Index%
return


As jaco has mentioned, RegExBuddy, amongst many other regex test matching modules that can be found on the web, has a global option available that AHK cannot use in its version of regex. This is not some bug of AHK though, as many applications and programming languages implement regex in unique ways.

The examples jaco and I provided would be examples you could use to manually build your own pseudo-array using regexmatch to filter out the array elements (which would have an added advantage in that you can create a zero element to represent how many array elements there are).

I would tend to agree with you, though, that the power of using a while loop in combination with RegExMatch for that purpose is non-existent in the manual, yet you will find that it a frequently used solution here at the forums.
_________________
Try Quick Search for Autohotkey or see the tutorial for newbies.
Back to top
View user's profile Send private message Send e-mail
nick



Joined: 24 Aug 2005
Posts: 549
Location: Berlin / Germany

PostPosted: Sun Mar 21, 2010 9:40 am    Post subject: Reply with quote

... using RegExReplace instead with AutoHotkey

Code:
#NoEnv
Test := "ab1.1 22 33 44 55 66 77 88 99 0.0yz"
MatchList := RegExReplace(Test, "[^\d]*(\d+\.\d+|\d+)[^\d]*", "$1|", Matches)
StringSplit, Match, MatchList, |
Message := ""
Loop, %Matches%
   Message .= "Match" . A_Index . " = " . Match%A_Index% . "`n"
MsgBox, %MatchList%`n`n%Message%
ExitApp

_________________
nick Wink
Back to top
View user's profile Send private message
Larry



Joined: 03 Mar 2005
Posts: 61

PostPosted: Mon Mar 22, 2010 2:07 am    Post subject: Thanks for the education Reply with quote

Thanks for all the help guys. Your willingness to help us nonprogrammers is what makes this forum great. And it benefits everyone in these forums whether it comes in the form of more script postings or just more searchable material for others exeriencing similar problems to what I had.

Thanks again.
Larry
Back to top
View user's profile Send private message
ton80



Joined: 18 Dec 2009
Posts: 62

PostPosted: Sun Mar 20, 2011 7:31 pm    Post subject: Reply with quote

jaco0646 wrote:
RegExMatch is not global. It fills an array only "If any capturing subpatterns are present..."

For global matching you need something like grep(). You may also just use RegExMatch in a loop.
Code:
test = ab1.1 22 33 44 55 66 77 88 99 0.0yz

pos = 1
While pos := RegExMatch(test,"[\d\.]+", match, pos+StrLen(match))
 MsgBox,% match


Thank you very much for this. It was very helpful.
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    AutoHotkey Community Forum Index -> Ask for Help All times are GMT
Page 1 of 1

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group