Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

RegExMatchAll()


  • Please log in to reply
3 replies to this topic
Rapte_Of_Suzaku
  • Members
  • 901 posts
  • Last active: Jul 08 2011 02:12 PM
  • Joined: 29 Feb 2008
Returns an object containing every match and every captured subpattern (requires AHK build supporting objects).

Comparisons to other similar scripts:grep() by polyethene limits you to getting back only 1 subpattern per match
RegExMatchArray() by Slanter was supposed to obtain all matches (even overlapping matches), but doesn't succeed in doing so. It also has the potential to get stuck in an infinite loop.
[AHK_L] RegExMatchArray() by Frankie again limits you to getting back only 1 subpattern per match
[stdlib] RegExMatchAll by derRaphael doesn't limit what you can get, but requires that you specifically request each desired subpattern through a separate "MatchDefinition" parameter.

Example 1:
regexp := "(?P<Year>\d{4}).?(?P<Month>\d{2}).?(?P<Day>\d{2})"
text=
(
2010-11-11, 11:05
2000-07-22
2018-12-14, 16:37
2210-11-06
2001-01-13 <---- important?
2002-02-14, 04:46
2002-03-28
2010-11-11, 02:12
)
m := RegExMatchAll(text,regexp)

MsgBox % "there were " m.MaxIndex() " matches"
MsgBox % "3rd match = " m[3][0]
MsgBox % "'Month' subpattern of third match = " m[3]["Month"]

Example 2:
url := "http://www.autohotkey.com/forum/rss.php?t=1"
file := A_ScriptFullPath ".rss"
URLDownloadToFile, %file%, %url%
FileRead, text, %file%
FileDelete, %file%


regexp := "s)<item>\s*<title>(.+?)</title>.*?<link>(.+?)</link>"
matches := RegExMatchAll(text,regexp)

;dout_om(matches)
d:=""
for i,match in matches
{
    d.="Match #" i ":`n"
    for name,subpat in match
        d.="    " name " = '" subpat "'`n"
}
Msgbox %d%


The function:
; Applies Lexikos' ListGlobalVars() technique (http://www.autohotkey.com/forum/viewtopic.php?p=165430#165430)
RegExMatchAll(text, regexp, pos=1)
{
    ; prep work for getting list of local variables
    static hwndEdit, pSFW, pSW, bkpSFW, bkpSW
    if !hwndEdit
    {
        dhw := A_DetectHiddenWindows
        DetectHiddenWindows, On
        Process, Exist
        ControlGet, hwndEdit, Hwnd,, Edit1, ahk_class AutoHotkey ahk_pid %ErrorLevel%
        DetectHiddenWindows, %dhw%

        hmod := DllCall("GetModuleHandle", "str", "user32.dll")
        pSFW := DllCall("GetProcAddress", "uint", hmod, "astr", "SetForegroundWindow")
        pSW := DllCall("GetProcAddress", "uint", hmod, "astr", "ShowWindow")
        DllCall("VirtualProtect", "uint", pSFW, "uint", 8, "uint", 0x40, "uint*", 0)
        DllCall("VirtualProtect", "uint", pSW, "uint", 8, "uint", 0x40, "uint*", 0)
        bkpSFW := NumGet(pSFW+0, 0, "int64")
        bkpSW := NumGet(pSW+0, 0, "int64")
    }
    
    ; RegExMatch until there are no more matches
    ret := Object()
    n := i := 0
    While ( pos := RegExMatch(text, regexp, m%A_Index%_, pos) )
    {
        ret[++n] := Object()
        ret[n][0]:=m%A_Index%_
        pos+=StrLen(m%A_Index%_)
    }

    ; place convenient bookends for regexing matches
    m0_:="start"
    m__:="stop"

    ; get a list of local variables
    NumPut(0x0004C200000001B8, pSFW+0, 0, "int64")  ; return TRUE
    NumPut(0x0008C200000001B8, pSW+0, 0, "int64")   ; return TRUE
    ListVars
    NumPut(bkpSFW, pSFW+0, 0, "int64")
    NumPut(bkpSW, pSW+0, 0, "int64")
    ControlGetText, text,, ahk_id %hwndEdit%
    
    ; process list of local variables to place all match info into return object
    RegExMatch(text, "sm)^m0_.*(?:^m__.*Global Variables \(alphabetical\)`r`n-{50}`r`n)", matches)
    Loop Parse, matches, `n, `r
    {
        RegExMatch(A_LoopField,"m)^m(\d+)_(\S+)\[[^\]]*\]:",part)
        ret[part1][part2]:=m%part1%_%part2%
    }
    
    return ret
}

EDIT: Added an example to demonstrate how named subpatterns work (simple).


  • Guests
  • Last active:
  • Joined: --
if this function requires something other than ahk basic please state so.
Error in ahk basic

Error at line 23.

Line Text: for i,match in matches
Error: This line does not contain a recognized action.

The program will exit.

Remember that these forums support several flavors of ahk, and without stating any requirements beyound ahk basic is very likely to cause confusion and consternamtion for noobs.

SoLong&Thx4AllTheFish
  • Members
  • 4999 posts
  • Last active:
  • Joined: 27 May 2007
@Guest:

Returns an object containing every match and every captured subpattern (requires AHK build supporting objects).

so it was mentioned :D

birchy1978
  • Members
  • 40 posts
  • Last active: Jun 27 2011 03:01 AM
  • Joined: 16 Jul 2008
Hi guys

When I run this function using the examples provided it is causing AutoHotkey_L to crash? is anybody else able to get it to work?[/img]