AutoHotkey Community

It is currently May 27th, 2012, 3:07 am

All times are UTC [ DST ]




Post new topic Reply to topic  [ 12 posts ] 
Author Message
PostPosted: March 20th, 2010, 6:12 pm 
Offline

Joined: March 3rd, 2005, 5:43 am
Posts: 62
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?


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 20th, 2010, 6:28 pm 
Offline

Joined: October 7th, 2006, 4:50 pm
Posts: 3157
Location: MN, USA
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


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 20th, 2010, 6:33 pm 
Offline
User avatar

Joined: March 19th, 2008, 12:43 am
Posts: 5480
Location: the tunnel(?=light)
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. :D

_________________
Image
Try Quick Search for Autohotkey or see the tutorial for newbies.


Report this post
Top
 Profile  
Reply with quote  
PostPosted: March 20th, 2010, 10:40 pm 
Offline

Joined: March 3rd, 2005, 5:43 am
Posts: 62
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.


Report this post
Top
 Profile  
Reply with quote  
PostPosted: March 21st, 2010, 3:48 am 
Offline

Joined: April 8th, 2009, 8:23 pm
Posts: 3036
Location: Rio de Janeiro - RJ - Brasil
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.
"
Image
Antonio França
My stuff: Google Profile


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 21st, 2010, 4:29 am 
Offline

Joined: October 7th, 2006, 4:50 pm
Posts: 3157
Location: MN, USA
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?


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 21st, 2010, 5:27 am 
Offline
User avatar

Joined: May 24th, 2009, 5:35 am
Posts: 2099
Location: Iowa, USA
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"
}

_________________
Image
Recommended: AutoHotkey_L
Basic Webpage Controls


Report this post
Top
 Profile  
Reply with quote  
PostPosted: March 21st, 2010, 7:18 am 
Offline
User avatar

Joined: March 19th, 2008, 12:43 am
Posts: 5480
Location: the tunnel(?=light)
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.

_________________
Image
Try Quick Search for Autohotkey or see the tutorial for newbies.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 21st, 2010, 10:40 am 
Offline

Joined: August 24th, 2005, 5:29 pm
Posts: 549
Location: Berlin / Germany
... 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:


Report this post
Top
 Profile  
Reply with quote  
 Post subject: Thanks for the education
PostPosted: March 22nd, 2010, 3:07 am 
Offline

Joined: March 3rd, 2005, 5:43 am
Posts: 62
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


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 20th, 2011, 8:31 pm 
Offline

Joined: December 18th, 2009, 6:08 pm
Posts: 63
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.


Report this post
Top
 Profile  
Reply with quote  
 Post subject: Re:
PostPosted: April 28th, 2012, 1:39 pm 
ton80 wrote:
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.


I too was stuck on the exact same situation... spent over 2 days racking my brain as to why AHK was giving me blank 'array' values past 1... :(
This thread is helpful! thank you.


Report this post
Top
  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 12 posts ] 

All times are UTC [ DST ]


Who is online

Users browsing this forum: Bing [Bot], Google [Bot], rbrtryn, Yahoo [Bot] and 26 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group