rgx(): Function that uses ReGexMatch with GUI to test

Post your working scripts, libraries and tools for AHK v1.1 and older
jsong55
Posts: 219
Joined: 30 Mar 2021, 22:02

rgx(): Function that uses ReGexMatch with GUI to test

Post by jsong55 » 14 May 2021, 05:31

Update: 16/5/21

I've created a GUI to make it easier to test the function and regular expressions

I have used functions by @Maestrith, @FG, @Just Me
You'll need to download your own icons and modify line 22-24 of code

The rest is pretty self-explanatory within the Gui. Examples included within the Gui too.

Have fun!

Code: Select all

;OPTIMIZATIONS START
#NoEnv
#MaxHotkeysPerInterval 99000000
#HotkeyInterval 99000000
#KeyHistory 0
#WinActivateForce
ListLines Off
Process, Priority, , A
SetBatchLines, -1
SetKeyDelay, -1, -1
SetMouseDelay, -1
SetDefaultMouseSpeed, 0
SetWinDelay, -1
SetControlDelay, -1
SendMode Input
;OPTIMIZATIONS END
#SingleInstance, force

AHK_Scripts_location:="C:\Users\Name\Desktop\"

; set the location of your icons
icon:={"run":AHK_Scripts_location "AHK Scripts\icon\" . "run" . ".ico"
		, "close":AHK_Scripts_location "AHK Scripts\icon\" . "close" . ".ico"
		, "save":AHK_Scripts_location "AHK Scripts\icon\" . "save" . ".ico"}

;                                                            Usage               
;______________________________________________________________________________________________________________________________

/*
Load a list of files from a directory and search for them using regex

Perform a case insensitive search for file names that start with c and ends with .txt
Optionally: we can also find files that end with .mp3 or .jpg or .jpeg by changing the last subpattern
- mp3 - (\.mp3|\.txt|\.jpe*g)
*/
Files=
(
adam.txt
ali.docx
ben.txt
benny.docx
christine.txt
crystal.docx
Charlie.txt
Candy.jpg
Candyimage.jpeg
chime.mp3
)
results1:=rgx(files,"i)(c[a-zA-Z_0-9 ]+)(\.txt)")

results2:=rgx(files,"i)(c[a-zA-Z_0-9 ]+)(\.txt|\.mp3|\.jpe*g)")
; Msgbox,% "`n____________________________________`nResults 1: `n____________________________________`n"
;     . Obj2String(results1)
;     . "`n____________________________________`nResults 2: `n____________________________________`n"
;     . Obj2String(results2)


;                                                             GUI                
;______________________________________________________________________________________________________________________________

Gui,rg:New
Gui,rg:+Labelrg +Resize -Caption -border
Gui,rg:color,4ca1a3
Gui,rg:Font, s14 Arial
Gui,rg:Add,Text,hwndAXZ xm ym w350 h40 vtitle1,Input your values to search:
ctlcolors.attach(AXZ,"4ca1a3","WHITE")
Gui,rg:Add,Edit,hwndAXZ y+10 w350 r10 vInput,% Files
ctlcolors.attach(AXZ,"f2dac3","21094e")
GuiControlGet, textpos, pos, title1
Gui,rg:Add,Text,hwndAXZ y+section vtitle3,% "Regex String:" A_Tab A_Tab
ctlcolors.attach(AXZ,"4ca1a3","WHITE")
Gui,rg:Font, s10 Arial
Gui,rg:Add,Text,hwndAXZ yp+6 x+section gExample1,% "Example1" A_Tab
ctlcolors.attach(AXZ,"4ca1a3","WHITE")
Gui,rg:Add,Text,hwndAXZ x+section gExample2,Example2
ctlcolors.attach(AXZ,"4ca1a3","WHITE")

Gui,rg:Font, s14 Arial

Gui,rg:Add,Edit,hwndAXZ xm y+section w350 r5 vExpression, % "Click on the example hyperlinks above"
ctlcolors.attach(AXZ,"f1ca89","21094e")
Gui,rg:Add,Text,hwndAXZ y%textposy% x+section h40,Output your answers:
ctlcolors.attach(AXZ,"4ca1a3","WHITE")
Gui,rg:Add,Button,hwndAXZ +default gRUN x+section h40 w45,
file := AHK_Scripts_location "AHK Scripts\icon\" . file . ".ico"


GuiButtonIcon(AXZ, icon.run,, "s45")
; Gui,rg:Add,Button, gSave x+section,OK
Gui,rg:Add,Button,hwndAXZ +default gCLOSE x+section h40 w45,  
GuiButtonIcon(AXZ, icon.close,, "s45")
Gui,rg:Add,Button,hwndAXZ +default gSAVE x+section h40 w45,  
GuiButtonIcon(AXZ, icon.save,, "s45")
Gui,rg:Add,Edit,hwndAXZ x370 y+10 w350 h415 vOutput, Output answers
ctlcolors.attach(AXZ,"21094e","a5e1ad")
Gui,rg:show,Autosize
OnMessage(0x0201, "WM_LBUTTONDOWN")
Return

Example1:
GuiControl,rg:Text,Expression,% "i)(c[a-zA-Z_0-9 ]+)(\.txt)"
Return

Example2:
GuiControl,rg:Text,Expression,% "i)(c[a-zA-Z_0-9 ]+)(\.txt|\.mp3|\.jpe*g)"
Return
RUN:
Gui,rg:submit,nohide
outputobj:=rgx(Input,Expression)
Output:=Obj2String(outputobj)
GuiControl,rg:Text,output,% output
Return

CLOSE:
ExitApp
Return

Save:
Gui,rg:submit,nohide
FileContents:= ""
. ";                                                            Input               "
. "`n;______________________________________________________________________________________________________________________________"
. "`n" Input
. "`n;                                                         Expression    "         
. "`n;______________________________________________________________________________________________________________________________"
. "`n" Expression
. "`n;                                                           Output               "
. "`n;______________________________________________________________________________________________________________________________"
. "`n" Output "`n"


FileSelectFile, Destination, S2, RGX Output.txt, , Documents (*.txt)
If FileExist(Destination) {
    Msgbox,3,,Y - Append to existing file`nN - overwrite file
    IfMsgbox, Yes
        FileAppend, % FileContents,% Destination
    IfMsgbox, No ; overwrite
    {
        FileDelete, % Destination
        FileAppend, % FileContents,% Destination
    }
} Else If !(Destination="") {
        If !instr(Destination,".txt")
            Destination.=".txt"
        FileAppend, % FileContents,% Destination ; create brand new
    }

Return

rgsize:
GuiControl, Move, output, % "w" . A_GuiWidth-400 . " h" . A_GuiHeight-100
GuiControl, Move, jfastmsgboxv2, % "y" . A_GuiHeight - 50
GuiControl, Move, jfastmsgboxv3, % "y" . A_GuiHeight - 50
Gui,rg:color,4ca1a3
Return

WM_LBUTTONDOWN()
{
   If (A_Gui)
      PostMessage, 0xA1, 2
; 0xA1: WM_NCLBUTTONDOWN, refer to http://msdn.microsoft.com/en-us/library/ms645620%28v=vs.85%29.aspx
; 2: HTCAPTION (in a title bar), refer to http://msdn.microsoft.com/en-us/library/ms645618%28v=vs.85%29.aspx 
}


;                                                        This Function           
;______________________________________________________________________________________________________________________________

rgx(Haystack,Needle) {
    If !Instr(Needle,"(")
        Throw Exception("You need to pass in parentheses to use Named SubPatterns, use at least 1")
    Else
        n:=regexreplace(needle,"\(","",count) ; where count is the number of subpatterns
    p := 1, m := "", obj:={} ; m is the match

    Loop, % count+1 ; number of subpatterns plus 1 for the whole
        obj[A_Index]:={}
    
    While p:=RegexMatch(Haystack,needle,m,p + strlen(m)) { ; p is the position

        Loop, % count {
            i:=A_index
            If (i=1) {
                obj[i].push(m) ; m is the whole result
                obj[2].push(m%i%) ; m1 is the first subpattern
            } Else {
                obj[i+1].push(m%i%) ; m2, m3, etc
            }
        }
    }
    Return obj
}

;                                                Functions - by maestrith.com    
;______________________________________________________________________________________________________________________________
Obj2String(Obj,FullPath:=1,BottomBlank:=0){
	static String,Blank
	if(FullPath=1)
		String:=FullPath:=Blank:=""
	if(IsObject(Obj)){
		for a,b in Obj{
			if(IsObject(b))
				Obj2String(b,FullPath "." a,BottomBlank)
			else{
				if(BottomBlank=0)
					String.=FullPath "." a " = " b "`n"
				else if(b!="")
					String.=FullPath "." a " = " b "`n"
				else
					Blank.=FullPath "." a " =`n"
			}
	}}
	return String Blank
}

;                                                    Just Me's Ctl Colors        
;______________________________________________________________________________________________________________________________

; ======================================================================================================================
; AHK 1.1+
; ======================================================================================================================
; Function:          Auxiliary object to color controls on WM_CTLCOLOR... notifications.
;                    Supported controls are: Checkbox, ComboBox, DropDownList, Edit, ListBox, Radio, Text.
;                    Checkboxes and Radios accept only background colors due to design.
; Namespace:         CtlColors
; Tested with:       1.1.25.02
; Tested on:         Win 10 (x64)
; Change log:        1.0.04.00/2017-10-30/just me  -  added transparent background (BkColor = "Trans").
;                    1.0.03.00/2015-07-06/just me  -  fixed Change() to run properly for ComboBoxes.
;                    1.0.02.00/2014-06-07/just me  -  fixed __New() to run properly with compiled scripts.
;                    1.0.01.00/2014-02-15/just me  -  changed class initialization.
;                    1.0.00.00/2014-02-14/just me  -  initial release.
; ======================================================================================================================
; This software is provided 'as-is', without any express or implied warranty.
; In no event will the authors be held liable for any damages arising from the use of this software.
; ======================================================================================================================
Class CtlColors {
   ; ===================================================================================================================
   ; Class variables
   ; ===================================================================================================================
   ; Registered Controls
	Static Attached := {}
   ; OnMessage Handlers
	Static HandledMessages := {Edit: 0, ListBox: 0, Static: 0}
   ; Message Handler Function
	Static MessageHandler := "CtlColors_OnMessage"
   ; Windows Messages
	Static WM_CTLCOLOR := {Edit: 0x0133, ListBox: 0x134, Static: 0x0138}
   ; HTML Colors (BGR)
	Static HTML := {AQUA: 0xFFFF00, BLACK: 0x000000, BLUE: 0xFF0000, FUCHSIA: 0xFF00FF, GRAY: 0x808080, GREEN: 0x008000
                 , LIME: 0x00FF00, MAROON: 0x000080, NAVY: 0x800000, OLIVE: 0x008080, PURPLE: 0x800080, RED: 0x0000FF
                 , SILVER: 0xC0C0C0, TEAL: 0x808000, WHITE: 0xFFFFFF, YELLOW: 0x00FFFF, LIGHTSALMON: 0xFFA07A
				 , OFFWHITE: 0xfaf3f3, LIGHTGREY: 0xe1e5ea, MIDGREY:0xA7BBC7, DULLPINK:0xda7f8f}
   ; Transparent Brush
	Static NullBrush := DllCall("GetStockObject", "Int", 5, "UPtr")
   ; System Colors
	Static SYSCOLORS := {Edit: "", ListBox: "", Static: ""}
   ; Error message in case of errors
	Static ErrorMsg := ""
   ; Class initialization
	Static InitClass := CtlColors.ClassInit()
   ; ===================================================================================================================
   ; Constructor / Destructor
   ; ===================================================================================================================
	__New() { ; You must not instantiate this class!
		If (This.InitClass == "!DONE!") { ; external call after class initialization
			This["!Access_Denied!"] := True
			Return False
		}
	}
   ; ----------------------------------------------------------------------------------------------------------------
	__Delete() {
		If This["!Access_Denied!"]
			Return
		This.Free() ; free GDI resources
	}
   ; ===================================================================================================================
   ; ClassInit       Internal creation of a new instance to ensure that __Delete() will be called.
   ; ===================================================================================================================
	ClassInit() {
		CtlColors := New CtlColors
		Return "!DONE!"
	}
   ; ===================================================================================================================
   ; CheckBkColor    Internal check for parameter BkColor.
   ; ===================================================================================================================
	CheckBkColor(ByRef BkColor, Class) {
		This.ErrorMsg := ""
		If (BkColor != "") && !This.HTML.HasKey(BkColor) && !RegExMatch(BkColor, "^[[:xdigit:]]{6}$") {
			This.ErrorMsg := "Invalid parameter BkColor: " . BkColor
			Return False
		}
		BkColor := BkColor = "" ? This.SYSCOLORS[Class]
              :  This.HTML.HasKey(BkColor) ? This.HTML[BkColor]
              :  "0x" . SubStr(BkColor, 5, 2) . SubStr(BkColor, 3, 2) . SubStr(BkColor, 1, 2)
		Return True
	}
   ; ===================================================================================================================
   ; CheckTxColor    Internal check for parameter TxColor.
   ; ===================================================================================================================
	CheckTxColor(ByRef TxColor) {
		This.ErrorMsg := ""
		If (TxColor != "") && !This.HTML.HasKey(TxColor) && !RegExMatch(TxColor, "i)^[[:xdigit:]]{6}$") {
			This.ErrorMsg := "Invalid parameter TextColor: " . TxColor
			Return False
		}
		TxColor := TxColor = "" ? ""
              :  This.HTML.HasKey(TxColor) ? This.HTML[TxColor]
              :  "0x" . SubStr(TxColor, 5, 2) . SubStr(TxColor, 3, 2) . SubStr(TxColor, 1, 2)
		Return True
	}
   ; ===================================================================================================================
   ; Attach          Registers a control for coloring.
   ; Parameters:     HWND        - HWND of the GUI control                                   
   ;                 BkColor     - HTML color name, 6-digit hexadecimal RGB value, or "" for default color
   ;                 ----------- Optional 
   ;                 TxColor     - HTML color name, 6-digit hexadecimal RGB value, or "" for default color
   ; Return values:  On success  - True
   ;                 On failure  - False, CtlColors.ErrorMsg contains additional informations
   ; ===================================================================================================================
	Attach(HWND, BkColor, TxColor := "") {
      ; Names of supported classes
		Static ClassNames := {Button: "", ComboBox: "", Edit: "", ListBox: "", Static: ""}
      ; Button styles
		Static BS_CHECKBOX := 0x2, BS_RADIOBUTTON := 0x8
      ; Editstyles
		Static ES_READONLY := 0x800
      ; Default class background colors
		Static COLOR_3DFACE := 15, COLOR_WINDOW := 5
      ; Initialize default background colors on first call -------------------------------------------------------------
		If (This.SYSCOLORS.Edit = "") {
			This.SYSCOLORS.Static := DllCall("User32.dll\GetSysColor", "Int", COLOR_3DFACE, "UInt")
			This.SYSCOLORS.Edit := DllCall("User32.dll\GetSysColor", "Int", COLOR_WINDOW, "UInt")
			This.SYSCOLORS.ListBox := This.SYSCOLORS.Edit
		}
		This.ErrorMsg := ""
      ; Check colors ---------------------------------------------------------------------------------------------------
		If (BkColor = "") && (TxColor = "") {
			This.ErrorMsg := "Both parameters BkColor and TxColor are empty!"
			Return False
		}
      ; Check HWND -----------------------------------------------------------------------------------------------------
		If !(CtrlHwnd := HWND + 0) || !DllCall("User32.dll\IsWindow", "UPtr", HWND, "UInt") {
			This.ErrorMsg := "Invalid parameter HWND: " . HWND
			Return False
		}
		If This.Attached.HasKey(HWND) {
			This.ErrorMsg := "Control " . HWND . " is already registered!"
			Return False
		}
		Hwnds := [CtrlHwnd]
      ; Check control's class ------------------------------------------------------------------------------------------
		Classes := ""
		WinGetClass, CtrlClass, ahk_id %CtrlHwnd%
		This.ErrorMsg := "Unsupported control class: " . CtrlClass
		If !ClassNames.HasKey(CtrlClass)
			Return False
		ControlGet, CtrlStyle, Style, , , ahk_id %CtrlHwnd%
		If (CtrlClass = "Edit")
			Classes := ["Edit", "Static"]
		Else If (CtrlClass = "Button") {
			IF (CtrlStyle & BS_RADIOBUTTON) || (CtrlStyle & BS_CHECKBOX)
				Classes := ["Static"]
			Else
				Return False
		}
		Else If (CtrlClass = "ComboBox") {
			VarSetCapacity(CBBI, 40 + (A_PtrSize * 3), 0)
			NumPut(40 + (A_PtrSize * 3), CBBI, 0, "UInt")
			DllCall("User32.dll\GetComboBoxInfo", "Ptr", CtrlHwnd, "Ptr", &CBBI)
			Hwnds.Insert(NumGet(CBBI, 40 + (A_PtrSize * 2, "UPtr")) + 0)
			Hwnds.Insert(Numget(CBBI, 40 + A_PtrSize, "UPtr") + 0)
			Classes := ["Edit", "Static", "ListBox"]
		}
		If !IsObject(Classes)
			Classes := [CtrlClass]
      ; Check background color -----------------------------------------------------------------------------------------
		If (BkColor <> "Trans")
			If !This.CheckBkColor(BkColor, Classes[1])
				Return False
      ; Check text color -----------------------------------------------------------------------------------------------
		If !This.CheckTxColor(TxColor)
			Return False
      ; Activate message handling on the first call for a class --------------------------------------------------------
		For I, V In Classes {
			If (This.HandledMessages[V] = 0)
				OnMessage(This.WM_CTLCOLOR[V], This.MessageHandler)
			This.HandledMessages[V] += 1
		}
      ; Store values for HWND ------------------------------------------------------------------------------------------
		If (BkColor = "Trans")
			Brush := This.NullBrush
		Else
			Brush := DllCall("Gdi32.dll\CreateSolidBrush", "UInt", BkColor, "UPtr")
		For I, V In Hwnds
			This.Attached[V] := {Brush: Brush, TxColor: TxColor, BkColor: BkColor, Classes: Classes, Hwnds: Hwnds}
      ; Redraw control -------------------------------------------------------------------------------------------------
		DllCall("User32.dll\InvalidateRect", "Ptr", HWND, "Ptr", 0, "Int", 1)
		This.ErrorMsg := ""
		Return True
	}
   ; ===================================================================================================================
   ; Change          Change control colors.
   ; Parameters:     HWND        - HWND of the GUI control
   ;                 BkColor     - HTML color name, 6-digit hexadecimal RGB value, or "" for default color
   ;                 ----------- Optional 
   ;                 TxColor     - HTML color name, 6-digit hexadecimal RGB value, or "" for default color
   ; Return values:  On success  - True
   ;                 On failure  - False, CtlColors.ErrorMsg contains additional informations
   ; Remarks:        If the control isn't registered yet, Add() is called instead internally.
   ; ===================================================================================================================
	Change(HWND, BkColor, TxColor := "") {
      ; Check HWND -----------------------------------------------------------------------------------------------------
		This.ErrorMsg := ""
		HWND += 0
		If !This.Attached.HasKey(HWND)
			Return This.Attach(HWND, BkColor, TxColor)
		CTL := This.Attached[HWND]
      ; Check BkColor --------------------------------------------------------------------------------------------------
		If (BkColor <> "Trans")
			If !This.CheckBkColor(BkColor, CTL.Classes[1])
				Return False
      ; Check TxColor ------------------------------------------------------------------------------------------------
		If !This.CheckTxColor(TxColor)
			Return False
      ; Store Colors ---------------------------------------------------------------------------------------------------
		If (BkColor <> CTL.BkColor) {
			If (CTL.Brush) {
				If (Ctl.Brush <> This.NullBrush)
					DllCall("Gdi32.dll\DeleteObject", "Prt", CTL.Brush)
				This.Attached[HWND].Brush := 0
			}
			If (BkColor = "Trans")
				Brush := This.NullBrush
			Else
				Brush := DllCall("Gdi32.dll\CreateSolidBrush", "UInt", BkColor, "UPtr")
			For I, V In CTL.Hwnds {
				This.Attached[V].Brush := Brush
				This.Attached[V].BkColor := BkColor
			}
		}
		For I, V In Ctl.Hwnds
			This.Attached[V].TxColor := TxColor
		This.ErrorMsg := ""
		DllCall("User32.dll\InvalidateRect", "Ptr", HWND, "Ptr", 0, "Int", 1)
		Return True
	}
   ; ===================================================================================================================
   ; Detach          Stop control coloring.
   ; Parameters:     HWND        - HWND of the GUI control
   ; Return values:  On success  - True
   ;                 On failure  - False, CtlColors.ErrorMsg contains additional informations
   ; ===================================================================================================================
	Detach(HWND) {
		This.ErrorMsg := ""
		HWND += 0
		If This.Attached.HasKey(HWND) {
			CTL := This.Attached[HWND].Clone()
			If (CTL.Brush) && (CTL.Brush <> This.NullBrush)
				DllCall("Gdi32.dll\DeleteObject", "Prt", CTL.Brush)
			For I, V In CTL.Classes {
				If This.HandledMessages[V] > 0 {
					This.HandledMessages[V] -= 1
					If This.HandledMessages[V] = 0
						OnMessage(This.WM_CTLCOLOR[V], "")
			}  }
			For I, V In CTL.Hwnds
				This.Attached.Remove(V, "")
			DllCall("User32.dll\InvalidateRect", "Ptr", HWND, "Ptr", 0, "Int", 1)
			CTL := ""
			Return True
		}
		This.ErrorMsg := "Control " . HWND . " is not registered!"
		Return False
	}
   ; ===================================================================================================================
   ; Free            Stop coloring for all controls and free resources.
   ; Return values:  Always True.
   ; ===================================================================================================================
	Free() {
		For K, V In This.Attached
			If (V.Brush) && (V.Brush <> This.NullBrush)
				DllCall("Gdi32.dll\DeleteObject", "Ptr", V.Brush)
		For K, V In This.HandledMessages
			If (V > 0) {
				OnMessage(This.WM_CTLCOLOR[K], "")
				This.HandledMessages[K] := 0
			}
		This.Attached := {}
		Return True
	}
   ; ===================================================================================================================
   ; IsAttached      Check if the control is registered for coloring.
   ; Parameters:     HWND        - HWND of the GUI control
   ; Return values:  On success  - True
   ;                 On failure  - False
   ; ===================================================================================================================
	IsAttached(HWND) {
		Return This.Attached.HasKey(HWND)
	}
}
; ======================================================================================================================
; CtlColors_OnMessage
; This function handles CTLCOLOR messages. There's no reason to call it manually!
; ======================================================================================================================
CtlColors_OnMessage(HDC, HWND) {
   Critical
   If CtlColors.IsAttached(HWND) {
      CTL := CtlColors.Attached[HWND]
      If (CTL.TxColor != "")
         DllCall("Gdi32.dll\SetTextColor", "Ptr", HDC, "UInt", CTL.TxColor)
      If (CTL.BkColor = "Trans")
         DllCall("Gdi32.dll\SetBkMode", "Ptr", HDC, "UInt", 1) ; TRANSPARENT = 1
      Else
         DllCall("Gdi32.dll\SetBkColor", "Ptr", HDC, "UInt", CTL.BkColor)
      Return CTL.Brush
   }
}

;{ GuiButtonIcon
; Fanatic Guru
; 2014 05 31
; Version 2.0
;
; FUNCTION to Assign an Icon to a Gui Button
;
;------------------------------------------------
;
; Method:
;   GuiButtonIcon(Handle, File, Options)
;
;   Parameters:
;   1) {Handle} 	HWND handle of Gui button
;   2) {File} 		File containing icon image
;   3) {Index} 		Index of icon in file
;						Optional: Default = 1
;   4) {Options}	Single letter flag followed by a number with multiple options delimited by a space
;						W = Width of Icon (default = 16)
;						H = Height of Icon (default = 16)
;						S = Size of Icon, Makes Width and Height both equal to Size
;						L = Left Margin
;						T = Top Margin
;						R = Right Margin
;						B = Botton Margin
;						A = Alignment (0 = left, 1 = right, 2 = top, 3 = bottom, 4 = center; default = 4)
;
; Return:
;   1 = icon found, 0 = icon not found
;
; Example:
; Gui, Add, Button, w70 h38 hwndIcon, Save
; GuiButtonIcon(Icon, "shell32.dll", 259, "s30 a1 r2")
; Gui, Show
;
GuiButtonIcon(Handle, File, Index := 1, Options := "")
{
	RegExMatch(Options, "i)w\K\d+", W), (W="") ? W := 16 :
	RegExMatch(Options, "i)h\K\d+", H), (H="") ? H := 16 :
	RegExMatch(Options, "i)s\K\d+", S), S ? W := H := S :
	RegExMatch(Options, "i)l\K\d+", L), (L="") ? L := 0 :
	RegExMatch(Options, "i)t\K\d+", T), (T="") ? T := 0 :
	RegExMatch(Options, "i)r\K\d+", R), (R="") ? R := 0 :
	RegExMatch(Options, "i)b\K\d+", B), (B="") ? B := 0 :
	RegExMatch(Options, "i)a\K\d+", A), (A="") ? A := 4 :
	Psz := A_PtrSize = "" ? 4 : A_PtrSize, DW := "UInt", Ptr := A_PtrSize = "" ? DW : "Ptr"
	VarSetCapacity( button_il, 20 + Psz, 0 )
	NumPut( normal_il := DllCall( "ImageList_Create", DW, W, DW, H, DW, 0x21, DW, 1, DW, 1 ), button_il, 0, Ptr )	; Width & Height
	NumPut( L, button_il, 0 + Psz, DW )		; Left Margin
	NumPut( T, button_il, 4 + Psz, DW )		; Top Margin
	NumPut( R, button_il, 8 + Psz, DW )		; Right Margin
	NumPut( B, button_il, 12 + Psz, DW )	; Bottom Margin	
	NumPut( A, button_il, 16 + Psz, DW )	; Alignment
	SendMessage, BCM_SETIMAGELIST := 5634, 0, &button_il,, AHK_ID %Handle%
	return IL_Add( normal_il, File, Index )
}
and perhaps some people can improve on the code. I improved slightly on someone's submission here with the "while p:=" method. Unfortunately, can't find the post. If someone finds it, I'll update to give credit.
@Joe Glines maybe you can feature this in your next video. I'm a fan! :)

AHK Documentation:
https://www.autohotkey.com/docs/commands/RegExMatch.htm

Code: Select all

;OPTIMIZATIONS START
#NoEnv
#MaxHotkeysPerInterval 99000000
#HotkeyInterval 99000000
#KeyHistory 0
#WinActivateForce
ListLines Off
Process, Priority, , A
SetBatchLines, -1
SetKeyDelay, -1, -1
SetMouseDelay, -1
SetDefaultMouseSpeed, 0
SetWinDelay, -1
SetControlDelay, -1
SendMode Input
;OPTIMIZATIONS END

;                                                            Usage               
;______________________________________________________________________________________________________________________________

/*
Load a list of files from a directory and search for them using regex

Perform a case insensitive search for file names that start with c and ends with .txt
Optionally: we can also find files that end with .mp3 or .jpg or .jpeg by changing the last subpattern
- mp3 - (\.mp3|\.txt|\.jpe*g)
*/
Files=
(
adam.txt
ali.docx
ben.txt
benny.docx
christine.txt
crystal.docx
Charlie.txt
Candy.jpg
Candyimage.jpeg
chime.mp3
)
results1:=rgx(files,"i)(c[a-zA-Z_0-9 ]+)(\.txt)")

results2:=rgx(files,"i)(c[a-zA-Z_0-9 ]+)(\.txt|\.mp3|\.jpe*g)")
Msgbox,% "`n____________________________________`nResults 1: `n____________________________________`n"
    . Obj2String(results1)
    . "`n____________________________________`nResults 2: `n____________________________________`n"
    . Obj2String(results2)

;                                                        This Function           
;______________________________________________________________________________________________________________________________

rgx(Haystack,Needle) {
    If !Instr(Needle,"(")
        Throw Exception("You need to pass in parentheses to use Named SubPatterns, use at least 1")
    Else
        n:=regexreplace(needle,"\(","",count) ; where count is the number of subpatterns
    p := 1, m := "", obj:={} ; m is the match

    Loop, % count+1 ; number of subpatterns plus 1 for the whole
        obj[A_Index]:={}
    
    While p:=RegexMatch(Haystack,needle,m,p + strlen(m)) { ; p is the position

        Loop, % count {
            i:=A_index
            If (i=1) {
                obj[i].push(m) ; m is the whole result
                obj[2].push(m%i%) ; m1 is the first subpattern
            } Else {
                obj[i+1].push(m%i%) ; m2, m3, etc
            }
        }
    }
    Return obj
}

;                                                Functions - by maestrith.com    
;______________________________________________________________________________________________________________________________
Obj2String(Obj,FullPath:=1,BottomBlank:=0){
	static String,Blank
	if(FullPath=1)
		String:=FullPath:=Blank:=""
	if(IsObject(Obj)){
		for a,b in Obj{
			if(IsObject(b))
				Obj2String(b,FullPath "." a,BottomBlank)
			else{
				if(BottomBlank=0)
					String.=FullPath "." a " = " b "`n"
				else if(b!="")
					String.=FullPath "." a " = " b "`n"
				else
					Blank.=FullPath "." a " =`n"
			}
	}}
	return String Blank
}

Return to “Scripts and Functions (v1)”