 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
Larry
Joined: 03 Mar 2005 Posts: 61
|
Posted: Sat Mar 20, 2010 5:12 pm Post subject: Re: RegExMatch, Why is it not finding all the subpatterns? |
|
|
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 |
|
 |
jaco0646
Joined: 07 Oct 2006 Posts: 3113 Location: MN, USA
|
Posted: Sat Mar 20, 2010 5:28 pm Post subject: |
|
|
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 |
|
 |
sinkfaze
Joined: 18 Mar 2008 Posts: 5044 Location: the tunnel(?=light)
|
Posted: Sat Mar 20, 2010 5:33 pm Post subject: |
|
|
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.  _________________ Try Quick Search for Autohotkey or see the tutorial for newbies. |
|
| Back to top |
|
 |
Larry
Joined: 03 Mar 2005 Posts: 61
|
Posted: Sat Mar 20, 2010 9:40 pm Post subject: Thank you to both sinkfaze and jaco0646 |
|
|
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 |
|
 |
MasterFocus
Joined: 08 Apr 2009 Posts: 3035 Location: Rio de Janeiro - RJ - Brasil
|
Posted: Sun Mar 21, 2010 2:48 am Post subject: Re: Thank you to both sinkfaze and jaco0646 |
|
|
| 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 |
|
 |
jaco0646
Joined: 07 Oct 2006 Posts: 3113 Location: MN, USA
|
Posted: Sun Mar 21, 2010 3:29 am Post subject: |
|
|
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 |
|
 |
jethrow
Joined: 24 May 2009 Posts: 1907 Location: Iowa, USA
|
Posted: Sun Mar 21, 2010 4:27 am Post subject: |
|
|
| 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"
} |
_________________
- in case I forgot to smile
Basic Webpage Controls
COM Object Reference |
|
| Back to top |
|
 |
sinkfaze
Joined: 18 Mar 2008 Posts: 5044 Location: the tunnel(?=light)
|
Posted: Sun Mar 21, 2010 6:18 am Post subject: Re: Thank you to both sinkfaze and jaco0646 |
|
|
| 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 |
|
 |
nick
Joined: 24 Aug 2005 Posts: 549 Location: Berlin / Germany
|
Posted: Sun Mar 21, 2010 9:40 am Post subject: |
|
|
... 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  |
|
| Back to top |
|
 |
Larry
Joined: 03 Mar 2005 Posts: 61
|
Posted: Mon Mar 22, 2010 2:07 am Post subject: Thanks for the education |
|
|
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 |
|
 |
ton80
Joined: 18 Dec 2009 Posts: 62
|
Posted: Sun Mar 20, 2011 7:31 pm Post subject: |
|
|
| 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 |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|