RegExMatch Match.Count is 0, not as expected Topic is solved

Get help with using AutoHotkey (v2 or newer) and its commands and hotkeys
valuex
Posts: 86
Joined: 01 Nov 2014, 08:17

RegExMatch Match.Count is 0, not as expected

14 Jan 2024, 05:07

I am trying to get the last occurance position of a char in a string as below.
But it's wired that the ObjMatch.Count is always 0.
Any idea to fix it? Thanks.

Code: Select all

msgbox Str_LastCharPos("1.2.33.",".")


Str_LastCharPos(InputStr,InChar)
{
    if(InStr("\.*?+[{|()^$",InChar))
        InChar:="\" . InChar ; Escape some chars
    Pos:=RegExMatch(InputStr, InChar , &ObjMatch, 1)
    If(Pos>0)
    {
        MatchNumber:=ObjMatch.Count
		msgbox MatchNumber
        LastMatchPos:=ObjMatch.Pos[MatchNumber]
        return LastMatchPos
    }
    else
        return 0
}

just me
Posts: 9542
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: RegExMatch Match.Count is 0, not as expected  Topic is solved

14 Jan 2024, 05:25

Match Object (RegExMatchInfo)
Match.Count: Returns the overall number of subpatterns (capturing groups), which is also the maximum value for N.
Your RegEx has no subpatterns.

If you want to search for a single character, why don't you use

Code: Select all

    Pos := InStr(InputStr, InChar, 1, -1)
valuex
Posts: 86
Joined: 01 Nov 2014, 08:17

Re: RegExMatch Match.Count is 0, not as expected

14 Jan 2024, 05:38

Oh, I get it. The NeedleRegE shall be enclosed with parentheses like: (reg_pattern).
Thans for your reply.
william_ahk
Posts: 501
Joined: 03 Dec 2018, 20:02

Re: RegExMatch Match.Count is 0, not as expected

14 Jan 2024, 06:26

It's because AHK never implemented a global flag for regex matches. (Have a look at the author's genius comment about this here if anyone is interested).
So you're only going to match the first occurrence. And also because there is no group in the pattern, the overall match will be at Match[0], which is confusing and got me in the past since index starts at 1 in AHK.

To implement a global match:

Code: Select all

msgbox Str_LastCharPos("1.2.33.",".")

Str_LastCharPos(InputStr,InChar)
{
	InChar := "\Q" InChar "\E" ; Pattern as literal
	StartingPos := 1
	Pos := 0
	While (FoundPos := RegExMatch(InputStr, InChar, &ObjMatch, StartingPos))
	{
		StartingPos := Pos + StrLen(ObjMatch[0])
		Pos := FoundPos
	}
	return Pos
}
Or, if you're only matching characters verbatim, just use InStr which supports searching backwards (and occurrence) as just me suggested:

Code: Select all

Str_LastCharPos(InputStr,InChar)
{
	Return InStr(InputStr, InChar, 1, -1)
}
Last edited by william_ahk on 14 Jan 2024, 06:40, edited 1 time in total.
User avatar
boiler
Posts: 17242
Joined: 21 Dec 2014, 02:44

Re: RegExMatch Match.Count is 0, not as expected

14 Jan 2024, 06:35

No loop is needed if you write the pattern to match the last instance of the character:

Code: Select all

#Requires AutoHotkey v2.0

msgbox Str_LastCharPos("1.2.33.",".")


Str_LastCharPos(InputStr,InChar)
{
    if(InStr("\.*?+[{|()^$",InChar))
        InChar:="\" . InChar ; Escape some chars
    return RegExMatch(InputStr, '.*\K' InChar)
}

Return to “Ask for Help (v2)”

Who is online

Users browsing this forum: Google [Bot] and 25 guests