Popular Post pixelsearch Posted February 12, 2023 Popular Post Share Posted February 12, 2023 (edited) Hi everybody Here is the script I use to test RegEx patterns offline, it's handy. Credits go to Lazycat, who scripted it initially many years ago and thanked "w0uter for ideas and parts of code". I added some modifications (listed in next post) and would like to thank @mLipok @mikell @Nine @mistersquirrle and @ioa747 for their contribution. expandcollapse popup;================================================================= ; Description: Testing Regular Expressions on the fly ; Requirement(s): Autoit 3.3.14.5 (2018) ; Author(s): YDY (Lazycat), thanks to w0uter for ideas and parts of code ; Modified: pixelsearch ; Version: 2.5p ;================================================================= #include <ComboConstants.au3> #include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <MsgBoxConstants.au3> #include <TabConstants.au3> #include <WindowsConstants.au3> Global $hDll = DllOpen("user32.dll") ; for DllCall's in _TrackPopupMenu() : purpose is not open/close Dll at each call (on-line help) Global $_g_bWasAChange = True ; mLipok, cf Func WM_COMMAND() Global $nMode = 0, $APP_VER = "2.5p" Global $sIniFile = @ScriptDir & "\" & StringTrimRight(@ScriptName, 4) & ".ini" Global $sTxtFile = StringTrimRight($sIniFile, 4) & ".txt" ; read/write "match text" edit control in a separate txt file (no more size limit) Global $aInfo, $mPos, $nColor, $sOldResult, $sOldCount #Region ### START Koda GUI section ### Form=RegExpQuickTester.kxf Global $hGUI = GUICreate("RegExp Quick Tester " & $APP_VER, 460, 598, -1, -1, _ BitOR($GUI_SS_DEFAULT_GUI, $WS_MAXIMIZEBOX, $WS_SIZEBOX), _ $WS_EX_ACCEPTFILES) ; accept to Maximize & Resize the GUI, also accept drag & drop Global $aGUIInitPos = WinGetPos($hGUI) ; see Func WM_GETMINMAXINFO ;========== $grpMatch = GUICtrlCreateGroup("Match Text", 4, 6, 449, 145) $ebTest = GUICtrlCreateEdit("", 12, 23, 434, 121, BitOR($ES_WANTRETURN, $WS_VSCROLL)) ; no horizontal scrollbar ; $ebTest = GUICtrlCreateEdit("", 12, 23, 434, 121) ; user may prefer this line, in case he needs an horizontal scrollbar GUICtrlSetFont(-1, 9, 400, 0, "Courier New") GUICtrlSetState(-1, $GUI_DROPACCEPTED) ; drag & drop accepted in "match text" edit control GUICtrlSendMsg($ebTest, $EM_LIMITTEXT, -1, 0) ; added to allow unlimited text size in edit control : ini file won't store this control anymore, a separate txt file will. GUICtrlCreateGroup("", -99, -99, 1, 1) ;========== $grpExpressions = GUICtrlCreateGroup("Expressions (right click for menu)", 4, 156, 449, 145, -1, $WS_EX_TRANSPARENT) $tabExpr = GUICtrlCreateTab(8, 174, 442, 121, BitOR($TCS_BUTTONS, $TCS_FLATBUTTONS, $TCS_FOCUSONBUTTONDOWN)) GUICtrlSetFont(-1, 8, 400, 0, "MS Sans Serif") GUICtrlSetResizing(-1, $GUI_DOCKAUTO) $TabSheet0 = GUICtrlCreateTabItem("Search Pattern") $ebRegExp = GUICtrlCreateEdit("", 12, 201, 434, 90, BitOR($ES_WANTRETURN,$WS_VSCROLL)) GUICtrlSetFont(-1, 11, 400, 0, "Lucida Console") $TabSheet1 = GUICtrlCreateTabItem("Replace Pattern") $ebRegExpReplace = GUICtrlCreateEdit("", 12, 201, 434, 90, BitOR($ES_WANTRETURN,$WS_VSCROLL)) GUICtrlSetFont(-1, 11, 400, 0, "Lucida Console") $TabSheet2 = GUICtrlCreateTabItem("Result Prefix") $ebResultPrefix = GUICtrlCreateEdit("", 12, 201, 434, 90, BitOR($ES_WANTRETURN,$WS_VSCROLL)) GUICtrlSetFont(-1, 11, 400, 0, "Lucida Console") $TabSheet3 = GUICtrlCreateTabItem("Result Suffix") $ebResultSuffix = GUICtrlCreateEdit("", 12, 201, 434, 90, BitOR($ES_WANTRETURN,$WS_VSCROLL)) GUICtrlSetFont(-1, 11, 400, 0, "Lucida Console") $TabSheet4 = GUICtrlCreateTabItem("Personal") $ebPersonal = GUICtrlCreateEdit("", 12, 201, 434, 90, BitOR($ES_WANTRETURN,$WS_VSCROLL)) GUICtrlSetFont(-1, 11, 400, 0, "Lucida Console") GUICtrlCreateTabItem("") GUICtrlCreateGroup("", -99, -99, 1, 1) ; purpose of $Tab_Highlight[3][2] is to highlight a TabItem if its Edit control contains something (or don't highlight if it's empty) Global $Tab_Highlight[3][2] = [[$ebRegExpReplace], [$ebResultPrefix], [$ebResultSuffix]] ; Col 1 = False (not highlited) ;========== $grpResults = GUICtrlCreateGroup("Result", 4, 304, 449, 208) $lblCount = GUICtrlCreateLabel("", 12, 492, 300, 17) ; width increased to 300 (in case additional infos). Possible to increase => 434 $ebResult = GUICtrlCreateEdit("", 12, 324, 434, 164, BitOR($WS_HSCROLL, $WS_VSCROLL, $ES_READONLY, $WS_TABSTOP)) GUICtrlSetFont(-1, 9, 400, 0, "Courier New") GUICtrlCreateGroup("", -99, -99, 1, 1) ;========== $grpBehaviour = GUICtrlCreateGroup("Options", 4, 514, 329, 78) GUICtrlCreateLabel("Mode:", 16, 536, 34, 17) $cbMode = GUICtrlCreateCombo("", 56, 532, 265, 25, BitOR($CBS_DROPDOWNLIST,$CBS_AUTOHSCROLL)) GUICtrlSetData(-1, "0 - Return 0/1|1 - Return array of matches|2 - Return array of matches with full match|3 - Return array of global matches|4 - Return array of arrays of global matches") GUICtrlCreateLabel("Replace count:", 16, 564, 77, 17) $ibRepCount = GUICtrlCreateInput("0", 96, 560, 72, 21, BitOr($GUI_SS_DEFAULT_INPUT, $ES_NUMBER)) $udRepCount = GUICtrlCreateUpdown($ibRepCount) GUICtrlSetLimit(-1, 16384, 0) $cbLineNum = GUICtrlCreateCheckbox("Show group numbers", 201, 562, 127, 17) GUICtrlCreateGroup("", -99, -99, 1, 1) ;========== $btnCode = GUICtrlCreateButton("Code", 370, 514, 81, 25) $btnClear = GUICtrlCreateButton("Clear", 370, 543, 81, 25) $btnClose = GUICtrlCreateButton("Close", 370, 572, 81, 25) ;========== $lblDummy = GUICtrlCreateLabel("", 336, 552, 1, 1) ; 1 pixel size ! Good luck to click on it in the GUI :) $lblDummycontext = GUICtrlCreateContextMenu($lblDummy) $hDummycontext = GUICtrlGetHandle($lblDummyContext) ; for function _TrackPopupMenu() ; 25th march 2023 : context menu prepared in a separate function _PrepareContextMenu() Global $idMenu_Start, $idMenu_End ; +++ _PrepareContextMenu() ;========== GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### ; Reload recent data $nMode = Number(IniRead($sIniFile, "Main", "Mode", 0)) GUICtrlSendMsg($cbMode, $CB_SETCURSEL, $nMode, 0) GUICtrlSetState($cbLineNum, IniRead($sIniFile, "Main", "LineNum", 1)) GUICtrlSetData($ibRepCount, IniRead($sIniFile, "Main", "ReplaceCount", 0)) GUICtrlSetData($ebRegExp, BinaryToString(IniRead($sIniFile, "Main", "Pattern", ""), 4)) ; 4 = $SB_UTF8 (binary data is UTF8) GUICtrlSetData($ebRegExpReplace, BinaryToString(IniRead($sIniFile, "Main", "Replace", ""), 4)) GUICtrlSetData($ebResultPrefix, BinaryToString(IniRead($sIniFile, "Main", "Prefix", ""), 4)) GUICtrlSetData($ebResultSuffix, BinaryToString(IniRead($sIniFile, "Main", "Suffix", ""), 4)) GUICtrlSetData($ebPersonal, BinaryToString(IniRead($sIniFile, "Main", "Personal", ""), 4)) GUICtrlSetData($ebTest, FileRead($sTxtFile)) GUIRegisterMsg($WM_COMMAND, "WM_COMMAND") ; mLipok GUIRegisterMsg($WM_GETMINMAXINFO, "WM_GETMINMAXINFO") While 1 $aInfo = GUIGetCursorInfo() If IsArray($aInfo) Then If $aInfo[3] = 1 And $aInfo[4] = $ebRegExp Then ; right click ($aInfo[3] = 1) while hovering over Edit Control in TabSheet0 $mPos = MouseGetPos() _TrackPopupMenu($hGUI, $hDummycontext, $mPos[0], $mPos[1]) EndIf EndIf $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE, $btnClose IniWrite($sIniFile, "Main", "Mode", $nMode) IniWrite($sIniFile, "Main", "LineNum", GUICtrlRead($cbLineNum)) IniWrite($sIniFile, "Main", "ReplaceCount", Int(GUICtrlRead($ibRepCount))) IniWrite($sIniFile, "Main", "Pattern", StringToBinary(GUICtrlRead($ebRegExp), 4)) ; 4 = $SB_UTF8 (string data is UTF8) IniWrite($sIniFile, "Main", "Replace", StringToBinary(GUICtrlRead($ebRegExpReplace), 4)) IniWrite($sIniFile, "Main", "Prefix", StringToBinary(GUICtrlRead($ebResultPrefix), 4)) IniWrite($sIniFile, "Main", "Suffix", StringToBinary(GUICtrlRead($ebResultSuffix), 4)) IniWrite($sIniFile, "Main", "Personal", StringToBinary(GUICtrlRead($ebPersonal), 4)) Local $hTxtFile = FileOpen($sTxtFile, 2) ; 2 = Write mode (erase previous contents) FileWrite($hTxtFile, GUICtrlRead($ebTest)) FileClose($hTxtFile) DllClose($hDll) ; close user32.dll (was opened so DllCall's in _TrackPopupMenu() didn't open/close it at each call) Exit Case $idMenu_Start To $idMenu_End $sMenuData = GUICtrlRead($nMsg, 1) GUICtrlSendMsg($ebRegExp, 0x00C2, 1, StringLeft($sMenuData, StringInStr($sMenuData, @TAB)-1)) ; 0x00C2 = $EM_REPLACESEL ; 1 (or True) = allow Undo ; GUICtrlSetState($ebRegExp, $GUI_FOCUS) ; better caret position when line commented out. Case $cbMode $nMode = GUICtrlSendMsg($cbMode, $CB_GETCURSEL, 0, 0) Case $btnCode GUICtrlSetState($btnCode, $GUI_DISABLE) ; prevent accidental double click on the button _GenerateCode() ; generate AutoIt code and copy it to Clipboard GUICtrlSetState($btnCode, $GUI_ENABLE) Case $btnClear If MsgBox(BitOr($MB_YESNO, $MB_TOPMOST, $MB_ICONQUESTION, $MB_DEFBUTTON2), _ "Attention", "Clear all fields ?", 0, $hGUI) = $IDYES Then GUICtrlSetData($ebTest, "") GUICtrlSetData($ebRegExp, "") GUICtrlSetData($ebRegExpReplace, "") GUICtrlSetData($ebResultPrefix, "") GUICtrlSetData($ebResultSuffix, "") ; never clear the 'Personal' Tab here EndIf Case $GUI_EVENT_DROPPED If @GUI_DragId = -1 Then ; -1 means dragged from a file (only alternative is to drag from... Listview item : help file) GUICtrlSetData(@GUI_DropId, FileRead(@GUI_DragFile)) EndIf EndSwitch Check_Highlight() ; check 3 TabItems content (empty or not), then possibly turn on / off their highlight If $_g_bWasAChange Or ($nMsg <> 0 And $nMsg <> -11) Then ; mLipok for $_g_bWasAChange . $GUI_EVENT_MOUSEMOVE = -11 (me) RegExpExecute() $_g_bWasAChange = False EndIf WEnd ;================================================================= Func RegExpExecute() Local $vResult, $vTemp, $sResult = "Failed", $sCount = "", $error, $nCurColor Local $sResultPrefix = GUICtrlRead($ebResultPrefix), $sResultSuffix = GUICtrlRead($ebResultSuffix), _ $bShowGroupsNumber = (GUICtrlRead($cbLineNum) = $GUI_CHECKED) If GUICtrlRead($ebRegExpReplace) <> "" Then ; if Edit control "Replace Pattern" isn't empty => StringRegExpReplace If Not BitAND(GUICtrlGetState($cbMode), $GUI_DISABLE) Then GUICtrlSetState($cbMode, $GUI_DISABLE) If Not BitAND(GUICtrlGetState($ibRepCount), $GUI_ENABLE) Then GUICtrlSetState($ibRepCount, $GUI_ENABLE) If Not BitAND(GUICtrlGetState($cbLineNum), $GUI_DISABLE) Then GUICtrlSetState($cbLineNum, $GUI_DISABLE) ; added that one $sResult = $sResultPrefix & _ StringRegExpReplace(GUICtrlRead($ebTest), GUICtrlRead($ebRegExp), GUICtrlRead($ebRegExpReplace), GUICtrlRead($ibRepCount)) & _ $sResultSuffix $sCount = "Groups replaced: " & @extended & " (result length: " & StringLen($sResult) & ")" Else ; Edit control "Replace Pattern" is empty, so we're dealing now with "Search Pattern" Edit control => StringRegExp If Not BitAND(GUICtrlGetState($cbMode), $GUI_ENABLE) Then GUICtrlSetState($cbMode, $GUI_ENABLE) If Int(GUICtrlRead($ibRepCount)) <> 0 Then GUICtrlSetData($ibRepCount, 0) ; added that one If Not BitAND(GUICtrlGetState($ibRepCount), $GUI_DISABLE) Then GUICtrlSetState($ibRepCount, $GUI_DISABLE) If Not BitAND(GUICtrlGetState($cbLineNum), $GUI_ENABLE) Then GUICtrlSetState($cbLineNum, $GUI_ENABLE) ; added that one $nCurColor = 0 ; black $vResult = StringRegExp(GUICtrlRead($ebTest), GUICtrlRead($ebRegExp), $nMode) $error = @error $extended = @extended ; Workaround about editbox flickering If $error = 2 Then $nCurColor = 0xFF0000 ; red . $error = 2 means bad pattern (in any mode) If $nColor <> $nCurColor Then GUICtrlSetColor($ebRegExp, $nCurColor) $nColor = $nCurColor If $nMode = 0 Then If $vResult Then $sResult = "Matched" Else ; Mode 1/2/3/4 If Not $error Then $sResult = "" $vTemp = 0 If $nMode = 4 Then $sCount = "Global matches: " & UBound($vResult) For $i = 0 to UBound($vResult) - 1 If $i > 0 Then $sResult &= @CRLF ; version 2.5e : prevent here (& below) an annoying @CRLF at the end of the Result field $vTemp = $vResult[$i] $sResult &= "--- Global match " & $i+1 & " ---" & @CRLF For $j = 0 To UBound($vTemp) - 1 If $j > 0 Then $sResult &= @CRLF If $bShowGroupsNumber Then $sResult &= StringFormat("%0" & StringLen(String(UBound($vTemp))) & "d: %s", $j, $sResultPrefix & $vTemp[$j] & $sResultSuffix) Else $sResult &= $sResultPrefix & $vTemp[$j] & $sResultSuffix EndIf Next Next If IsArray($vTemp) Then $sCount = "Groups matched: " & UBound($vTemp) & " (global matches: " & UBound($vResult) & ")" Else ; Mode 1/2/3 $sCount = "Groups matched: " & UBound($vResult) & ($nMode < 3 ? (" (next offset: " & $extended & ")") : "") For $i = 0 to UBound($vResult) - 1 If $i > 0 Then $sResult &= @CRLF If $bShowGroupsNumber Then $sResult &= StringFormat("%0" & StringLen(String(UBound($vResult))) & "d: %s", $i, $sResultPrefix & $vResult[$i] & $sResultSuffix) Else $sResult &= $sResultPrefix & $vResult[$i] & $sResultSuffix EndIf Next EndIf EndIf EndIf EndIf If $sOldResult <> $sResult Or $sOldCount <> $sCount Then GUICtrlSetData($ebResult, $sResult) GUICtrlSetData($lblCount, $sCount) EndIf $sOldResult = $sResult $sOldCount = $sCount ; Wow... w0uter's workaround is still actual... ; Don't know, not recall what the prob was... ; StringRegExp('', Random(0x80000000, 0x7FFFFFFF), 1) EndFunc ;==>RegExpExecute ;================================================================= Func _TrackPopupMenu($hWnd, $hMenu, $x, $y) DllCall($hDll, "int", "TrackPopupMenuEx", "hwnd", $hMenu, "int", 0, "int", $x, "int", $y, "hwnd", $hWnd, "ptr", 0) EndFunc ;==>_TrackPopupMenu ;================================================================= Func Check_Highlight() For $i = 0 To 2 ; 3 TabItems to check If GUICtrlRead($Tab_Highlight[$i][0]) = "" Then ; if Edit control is empty in this TabItem... If $Tab_Highlight[$i][1] Then ; ...and if it's highlited... GUICtrlSendMsg($tabExpr, $TCM_HIGHLIGHTITEM, $i + 1, False) ; ...then don't highlight this TabItem $Tab_Highlight[$i][1] = False EndIf Else ; Edit control not empty in this TabItem... If Not $Tab_Highlight[$i][1] Then ; ...and if it's not highlited... GUICtrlSendMsg($tabExpr, $TCM_HIGHLIGHTITEM, $i + 1, True) ; ...then highlight this TabItem $Tab_Highlight[$i][1] = True EndIf EndIf Next EndFunc ;==>Check_Highlight ;================================================================= Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam) ; mLipok, reworked ; Local $hWndFrom = $lParam ; Local $iIDFrom = _WinAPI_LoWord($wParam) Local $iIDFrom = BitAND($wParam, 0xFFFF) ; same (cf WinAPIConv.au3) ; Local $iCode = _WinAPI_HiWord($wParam) Local $iCode = BitShift($wParam, 16) ; same (cf WinAPIConv.au3) Switch $iIDFrom Case $ebTest, $ebRegExp, $ebRegExpReplace, $ebResultPrefix, $ebResultSuffix, $ibRepCount Switch $iCode Case $EN_CHANGE ; Sent when the user has taken an action that may have altered text in an edit control (mLipok) $_g_bWasAChange = True If Not GUICtrlRead($ibRepCount) Then GUICtrlSetData($ibRepCount, 0) ; in case empty field => force 0 EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_COMMAND ;================================================================= Func WM_GETMINMAXINFO($hWnd, $iMsg, $wParam, $lParam) #forceref $iMsg, $wParam If $hWnd = $hGUI Then Local $minmaxinfo = DllStructCreate("int;int;int;int;int;int;int;int;int;int", $lParam) DllStructSetData($minmaxinfo, 7, $aGUIInitPos[2]) ; min width DllStructSetData($minmaxinfo, 8, $aGUIInitPos[3] / 1.5) ; min height, testing / 1.5 seems ok Return 0 ; "If an application processes this message, it should return zero." (msdn) EndIf Return $GUI_RUNDEFMSG EndFunc ;==>WM_GETMINMAXINFO ;================================================================= Func _GenerateCode() Local $sClipTxt, $sSubject, $sPattern $sSubject = _TextSplit(GUICtrlRead($ebTest), "$sSubject") ; 2nd param. used literally in generated code $sPattern = _TextSplit(GUICtrlRead($ebRegExp), "$sPattern") ; ditto If $sSubject = "" Or $sPattern = "" Then MsgBox(0, "Generating code", "error : Match Text OR Search Pattern are empty", 0, $hGUI) Return EndIf If Not GUICtrlRead($ebRegExpReplace) Then ; generate StringRegExp code If $nMode > 0 Then ; 1/2/3/4 $sClipTxt = "#include <Array.au3>" & @crlf & @crlf & _ "Local $sSubject, $sPattern, $aArray" & @crlf & @crlf & _ "$sSubject = " & $sSubject & @crlf & @crlf & _ "$sPattern = " & $sPattern & @crlf & @crlf & _ "$aArray = StringRegExp($sSubject, $sPattern, " & $nMode & ")" & @crlf & _ "If Not @error Then" & @crlf & _ " ; _CW($aArray)" & @crlf & _ ; interesting line used during tests (removable) " _ArrayDisplay($aArray)" & @crlf & _ "Else" & @crlf & _ " MsgBox(0, 'StringRegExp', 'error = ' & @error & (@error = 1 ? ' (no matches)' : ' (bad pattern)'))" & @crlf & _ "EndIf" & @crlf Else ; mode 0 doesn't generate an Array but an Int32 $sClipTxt = "Local $sSubject, $sPattern, $iMatch" & @crlf & @crlf & _ "$sSubject = " & $sSubject & @crlf & @crlf & _ "$sPattern = " & $sPattern & @crlf & @crlf & _ "$iMatch = StringRegExp($sSubject, $sPattern, " & $nMode & ")" & @crlf & _ "MsgBox(0, 'Matched ?', ($iMatch ? 'yes' : 'no'))" & @crlf EndIf Else ; generate StringRegExpReplace code Local $sReplace, $iCount $sReplace = _TextSplit(GUICtrlRead($ebRegExpReplace), "$sReplace") ; 2nd param. used literally in generated code $iCount = Int(GUICtrlRead($ibRepCount)) $sClipTxt = "Local $sSubject, $sPattern, $sReplace, $iCount, $sOutput" & @crlf & @crlf & _ "$sSubject = " & $sSubject & @crlf & @crlf & _ "$sPattern = " & $sPattern & @crlf & _ "$sReplace = " & $sReplace & @crlf & _ "$iCount = " & $iCount & (($iCount = 0) ? " ; 0 means global replacement" : "") & @crlf & @crlf & _ "$sOutput = StringRegExpReplace($sSubject, $sPattern, $sReplace, $iCount)" & @crlf & _ "MsgBox(0, 'StringRegExpReplace', $sOutput)" & @crlf EndIf ClipPut($sClipTxt) MsgBox(0, "Code (copied to Clipboard)", ClipGet(), 0, $hGUI) EndFunc ;==>_GenerateCode ;================================================================= Func _TextSplit($sString, $sCaller) Local $iMaxLineSize = 2000 ; changeable but tested ok . Though Scite MaxLine length = 4095, just think of ... ; ...possible plenty newline chars or ' expanded below, not forgetting possible @Tab characters expanded in Scite Local $iStringSize = StringLen($sString) ; ConsoleWrite("[" & $sCaller & "] " & "Initial $iStringSize = " & $iStringSize & @crlf & @crlf) Local $sLi = "", $iLiSize = 0, $b5CharsFound = False, $sRet = "" While $iStringSize > 0 $sLi = StringLeft($sString, $iMaxLineSize) $iLiSize = StringLen($sLi) ; important variable declared here, as $sLi is gonna be altered below. ; ConsoleWrite("[" & $sCaller & "] " & "$iLiSize = " & $iLiSize & @crlf) $sLi = "'" & StringReplace($sLi, "'", "''") & "'" ; surround with ' (by design) and double all eventual ' inside StringRegExp($sLi, '\R', 1) ; check 1st EOL match (if any) . EOL can be @crlf or @lf or @cr If Not @error Then ; EOL found in $sLi StringRegExp($sLi, "& '' ", 1) ; as there is (at least) 1 EOL in $sLi, check if these 5 problematic chars are found in $sLi $b5CharsFound = Not @error ? True : False ; if they're found => we'll keep them in $sLi after the 3 StringReplace() below $sLi = StringReplace($sLi, @crlf, "' & @crlf & '") ; @crlf first $sLi = StringReplace($sLi, @lf, "' & @lf & '") $sLi = StringReplace($sLi, @cr, "' & @cr & '") ; 3 following If's are useful, as they generate a simplified code If StringLeft($sLi, 5) = "'' & " Then $sLi = StringTrimLeft($sLi, 5) ; safe to execute this line (impossible '' in original) If StringRight($sLi, 5) = " & ''" Then $sLi = StringTrimRight($sLi, 5) ; ditto If Not $b5CharsFound Then ; If 5 original chars were not part of $sLi before the 3 StringReplace() above, then... $sLi = StringReplace($sLi, "& '' ", "") ; ...they may be part of $sLi now, in case several followed newlines at middle of $sLi were treated EndIf EndIf ; ConsoleWrite("[" & $sCaller & "] " & "Len $sLi altered = " & StringLen($sLi) & @crlf) ; ConsoleWrite("[" & $sCaller & "] " & "$sLi altered = " & $sLi & @crlf) If $sRet = "" Then ; 1st passage $sRet = $sLi Else $sRet &= @crlf & " " & $sCaller & " &= " & $sLi EndIf $sString = StringMid($sString, $iLiSize + 1) $iStringSize = StringLen($sString) ; ConsoleWrite("[" & $sCaller & "] " & "Remaining $iStringSize = " & $iStringSize & @crlf & @crlf) WEnd Return $sRet EndFunc ;==>_TextSplit ;================================================================= Func _PrepareContextMenu() ; Group here all GUICtrlCreateMenu() so their id's will precede all the Context menus lines id's defined by GUICtrlCreateMenuItem(...) below Local $mnu100 = GUICtrlCreateMenu("Options", $lblDummycontext) Local $mnu200 = GUICtrlCreateMenu("Anchors && Assertions", $lblDummycontext) Local $mnu300 = GUICtrlCreateMenu("Matching Characters", $lblDummycontext) Local $mnu400 = GUICtrlCreateMenu("Character Classes && Posix", $lblDummycontext) Local $mnu500 = GUICtrlCreateMenu("Groups && Backreferences", $lblDummycontext) Local $mnu600 = GUICtrlCreateMenu("Repeating Characters", $lblDummycontext) ; All Context menus items id's are defined in a single interval : from $idMenu_Start to $idMenu_End ; It will allow a simple test later, during the GUI loop : Case $idMenu_Start To $idMenu_End $idMenu_Start = GUICtrlCreateMenuItem("(?i)"&@TAB&"case-insensitive", $mnu100) GUICtrlCreateMenuItem("(?m)"&@TAB&"^ and $ match at newlines chars within data", $mnu100) GUICtrlCreateMenuItem("(?s)"&@TAB&". matches anything, including newline chars", $mnu100) GUICtrlCreateMenuItem("(?U)"&@TAB&"Ungreedy (quantifiers become lazy)", $mnu100) GUICtrlCreateMenuItem("(?x)"&@TAB&"ignore whitespace chars and # comments", $mnu100) GUICtrlCreateMenuItem("", $mnu100) GUICtrlCreateMenuItem("(?- )"&@TAB&"unset option(s) ex. (?-im) etc...", $mnu100) GUICtrlCreateMenuItem("^"&@TAB&"beginning of string, or after a newline if (?m)", $mnu200) GUICtrlCreateMenuItem("\A"&@TAB&"beginning of string, no matter (?m)", $mnu200) GUICtrlCreateMenuItem("\G"&@TAB&"beginning of string, then where previous match ended", $mnu200) GUICtrlCreateMenuItem("$"&@TAB&"end of string, or before a newline if (?m)", $mnu200) GUICtrlCreateMenuItem("\z"&@TAB&"end of string, no matter (?m)", $mnu200) GUICtrlCreateMenuItem("\Z"&@TAB&"end of string, or b4 newline at the end, no matter (?m)", $mnu200) GUICtrlCreateMenuItem("", $mnu200) GUICtrlCreateMenuItem("\b"&@TAB&"match at a word boundary", $mnu200) GUICtrlCreateMenuItem("\B"&@TAB&"match when not at a word boundary", $mnu200) GUICtrlCreateMenuItem("\K"&@TAB&"reset start of match at the current position", $mnu200) GUICtrlCreateMenuItem("(?= )"&@TAB&"positive lookahead q(?=u) q followed by u", $mnu200) GUICtrlCreateMenuItem("(?! )"&@TAB&"negative lookahead q(?!u) q not followed by u", $mnu200) GUICtrlCreateMenuItem("(?<= )"&@TAB&"positive lookbehind (?<=u)q q preceded by u", $mnu200) GUICtrlCreateMenuItem("(?<! )"&@TAB&"negative lookbehind (?<!u)q q not preceded by u", $mnu200) GUICtrlCreateMenuItem("."&@TAB&"any single character, except newline chars [^\r\n]", $mnu300) GUICtrlCreateMenuItem("|"&@TAB&"OR operator", $mnu300) GUICtrlCreateMenuItem("\"&@TAB&"escape a metacharacter \ ^ $ . [ | ( ) ? * + {", $mnu300) GUICtrlCreateMenuItem("\\"&@TAB&"match an actual backslash ", $mnu300) GUICtrlCreateMenuItem("\a"&@TAB&"alarm character (BEL, (chr(7))", $mnu300) GUICtrlCreateMenuItem("\d"&@TAB&"any digit (0-9)", $mnu300) GUICtrlCreateMenuItem("\D"&@TAB&"any non-digit", $mnu300) GUICtrlCreateMenuItem("\e"&@TAB&"escape character (chr(27))", $mnu300) GUICtrlCreateMenuItem("\f"&@TAB&"formfeed character (chr(12))", $mnu300) GUICtrlCreateMenuItem("\h"&@TAB&"any hor. whitespace (@TAB, space, non-break space)", $mnu300) GUICtrlCreateMenuItem("\H"&@TAB&"any non-horizontal whitespace", $mnu300) GUICtrlCreateMenuItem("\n"&@TAB&"newline character (@LF, chr(10))", $mnu300) GUICtrlCreateMenuItem("\N"&@TAB&"any character except newline chars, no matter (?s)", $mnu300) GUICtrlCreateMenuItem("\Q \E"&@TAB&"treat all enclosed characters as literals", $mnu300) GUICtrlCreateMenuItem("\r"&@TAB&"carriage return (@CR, chr(13))", $mnu300) GUICtrlCreateMenuItem("\R"&@TAB&"any newline sequence (@CRLF, @CR, @LF)", $mnu300) GUICtrlCreateMenuItem("\s"&@TAB&"any whitespace char : chr(9) to chr(13) and chr(32)", $mnu300) GUICtrlCreateMenuItem("\S"&@TAB&"any non-whitespace character", $mnu300) GUICtrlCreateMenuItem("\t"&@TAB&"tab character (@TAB, chr(9))", $mnu300) GUICtrlCreateMenuItem("\v"&@TAB&"any vertical whitespace : chr(10) to chr(13)", $mnu300) GUICtrlCreateMenuItem("\V"&@TAB&"any non-vertical whitespace", $mnu300) GUICtrlCreateMenuItem("\w"&@TAB&"any 'word' character: A-Z, a-z, 0-9 or underscore _", $mnu300) GUICtrlCreateMenuItem("\W"&@TAB&"any non-word character", $mnu300) GUICtrlCreateMenuItem("\xhh"&@TAB&"character with hexa code hh \x7E match a tilde ~", $mnu300) GUICtrlCreateMenuItem("\x{hhhh}"&@TAB&"character with hexa code hhhh \x{20AC} matches €", $mnu300) GUICtrlCreateMenuItem("[ ]"&@TAB&"match any character in the class", $mnu400) GUICtrlCreateMenuItem("[^ ]"&@TAB&"match any character not in the class", $mnu400) GUICtrlCreateMenuItem("[\\x0-9]"&@TAB&"match a backslash OR an x OR any digit", $mnu400) GUICtrlCreateMenuItem("[^0-9]"&@TAB&"match any non-digit character", $mnu400) GUICtrlCreateMenuItem("[\b]"&@TAB&"watch out: match a backspace (BS, (chr(8))", $mnu400) GUICtrlCreateMenuItem(""&@TAB&"5 metacharacters in a class are ^ \ - ] [ if posix", $mnu400) GUICtrlCreateMenuItem("", $mnu400) GUICtrlCreateMenuItem("[:alnum:]"&@TAB&"letters and digits, [A-Za-z0-9]", $mnu400) GUICtrlCreateMenuItem("[:alpha:]"&@TAB&"letters, [A-Za-z]", $mnu400) GUICtrlCreateMenuItem("[:ascii:]"&@TAB&"character codes, 0-127", $mnu400) GUICtrlCreateMenuItem("[:blank:]"&@TAB&"space or Tab only, [\x09\x20]", $mnu400) GUICtrlCreateMenuItem("[:cntrl:]"&@TAB&"control characters, 0-31 and 127", $mnu400) GUICtrlCreateMenuItem("[:digit:]"&@TAB&"decimal digits, \d or [0-9]", $mnu400) GUICtrlCreateMenuItem("[:graph:]"&@TAB&"printing characters, excluding space 33-126", $mnu400) GUICtrlCreateMenuItem("[:lower:]"&@TAB&"lower case characters, [a-z]", $mnu400) GUICtrlCreateMenuItem("[:print:]"&@TAB&"printing characters, including space 32-126", $mnu400) GUICtrlCreateMenuItem("[:punct:]"&@TAB&"punctuation !""#$%&&'()*+,-./:;<=>?@[\]^_`{|}~", $mnu400) GUICtrlCreateMenuItem("[:space:]"&@TAB&"whitespace, chr(9) to chr(13) and chr(32)", $mnu400) GUICtrlCreateMenuItem("[:upper:]"&@TAB&"uppercase letters, [A-Z]", $mnu400) GUICtrlCreateMenuItem("[:word:]"&@TAB&"word characters, \w or [[:alnum:]_]", $mnu400) GUICtrlCreateMenuItem("[:xdigit:]"&@TAB&"hexadecimal digits, [0-9A-Fa-f]", $mnu400) GUICtrlCreateMenuItem("", $mnu400) GUICtrlCreateMenuItem("[:^xdigit:]"&@TAB&"non-hexadecimal digits, [^0-9A-Fa-f] etc...", $mnu400) GUICtrlCreateMenuItem("( )"&@TAB&"capturing group", $mnu500) GUICtrlCreateMenuItem("(?: )"&@TAB&"non-capturing group", $mnu500) GUICtrlCreateMenuItem("(?| )"&@TAB&"non-capturing group with reset", $mnu500) GUICtrlCreateMenuItem("(?> )"&@TAB&"atomic non-capturing group (no backtrack)", $mnu500) GUICtrlCreateMenuItem("(?# )"&@TAB&"comment group (not nestable)", $mnu500) GUICtrlCreateMenuItem("(?<name> )"&@TAB&"named capturing group ex. (?<caps>[A-Z]+)", $mnu500) GUICtrlCreateMenuItem("", $mnu500) GUICtrlCreateMenuItem(""&@TAB&"Backreferences of previously captured groups", $mnu500) GUICtrlCreateMenuItem("\n"&@TAB&"absolute group number ex: \1 to \9", $mnu500) GUICtrlCreateMenuItem("\gn"&@TAB&"absolute group number (safer) ex: \g1", $mnu500) GUICtrlCreateMenuItem("\g{n}"&@TAB&"absolute group number (safest) ex: \g{1}", $mnu500) GUICtrlCreateMenuItem("\g{-n}"&@TAB&"relative group number ex: \g{-1}", $mnu500) GUICtrlCreateMenuItem("\k<name>"&@TAB&"named group ex: \k<caps>", $mnu500) GUICtrlCreateMenuItem(""&@TAB&"Repeat the previous character, class, group or backreference", $mnu600) GUICtrlCreateMenuItem("*"&@TAB&"0 or more times", $mnu600) GUICtrlCreateMenuItem("+"&@TAB&"1 or more times", $mnu600) GUICtrlCreateMenuItem("?"&@TAB&"0 or 1 time", $mnu600) GUICtrlCreateMenuItem("{x}"&@TAB&"exactly x times", $mnu600) GUICtrlCreateMenuItem("{x,}"&@TAB&"at least x times", $mnu600) GUICtrlCreateMenuItem("{,x}"&@TAB&"at most x times", $mnu600) GUICtrlCreateMenuItem("{x,y}"&@TAB&"between x and y times", $mnu600) GUICtrlCreateMenuItem("", $mnu600) GUICtrlCreateMenuItem("?"&@TAB&"(after any of the above) find the smallest match (ungreedy)", $mnu600) $idMenu_End = GUICtrlCreateMenuItem("+"&@TAB&"(after any of the above) possessive (e.g. atomic and greedy)", $mnu600) EndFunc ;==>_PrepareContextMenu Below are the match text & patterns corresponding to the pic above. For a start, you can copy and paste them in their respective edit control. After you choose the corresponding RegExp mode from the ComboBox at the bottom of the screen (mode 3 = return array of global matches) then you'll have the same results as displayed in the pic above. Match Text : blabla...blabla... blabla..."https://media.pic1.jpg"blabla..."https://media.pic2.png"... blabla..."https://media.pic3.jpg"blabla..."https://media.pic4.png"... blabla...blabla... Pattern : (?i)"([^"]+?\.(?:jpg|png))" When you end the script, 2 files will be created in the same directory of the script. Assuming your script is named "RegExpQuickTester 2.5p.au3", the 2 files created will be : * "RegExpQuickTester 2.5p.txt" which contains the saved Match Text that will be reused when you run the script. * "RegExpQuickTester 2.5p.ini" which contains the saved options that will be reused when you run the script. A right click while hovering over the Edit control of the Search Pattern will display a helpful context menu, with possibility to paste something from the menu inside the Search Pattern. Personally I nearly don't paste anything from the context menu but as this feature was created by the original scripter... Instead I like to consult this context menu as a RegExp syntax reminder ! Anyway, just experiment it and choose what's best for you. 99% of the time, the Search Pattern Tab will be on top. If you notice another colored Tab (except the Personal Tab which will never be highlited), then it means that there is something written in this other tab : the color is here only to remind you that there IS something in this other tab, in case you had forgotten. Even a space or a blank line would color the Tab. YJ This particular design (due to original scripter) won't allow you to type "" in the Replace Pattern Tab (mikell frowned, concerning this missing feature). Gladly I found that typing a non existing group, for example $99 will have the same effect as "" so it's a workaround that seems to do the job. The "Code" button allows you to generate the corresponding AutoIt code, which will be copied to the Clipboard Don't hesitate to ask if you have questions. Our RegExp gurus (that's not me) just love RegExp questions Edit: I forgot. You can drag a text file (or htm etc...) inside the Match Text edit control (it's a droppable zone) . There shouldn't be a 32Kb file size limit anymore as I added code to override this limit. There are probably a couple of other functionalities I'm not thinking of now, you'll easily find what you need if you look at the code. And if you want to modify something in the code, don't hesitate. Just share here your modifications in case other users find them useful too, thanks. Updates are detailed in next post Edited March 29, 2023 by pixelsearch Update to version 2.5p ioa747, funkey, BigDaddyO and 8 others 8 3 Link to comment Share on other sites More sharing options...
pixelsearch Posted February 12, 2023 Author Share Posted February 12, 2023 (edited) Revisions in RegExpQuickTester (sorted by descending order) ========= 25 mar 2023 : save & reload 5 Edit Tabs content with UTF-8 (to take care of Unicode characters) Context menu reworked with new items added, also context menu is now prepared in a separate function _PrepareContextMenu() Newlines (@CRLF and/or @LF and/or @CR) correctly parsed & copied in clipboard, e.g. Code button (for pasting directly in Scite) Ready : generated code > 4095 characters split in lines length acceptable by Scite, e.g < 4096 char) Display 'next offset' (e.g. @extended) for RegEx mode 1 & 2 when successful Changed version from "2.5j" to "2.5p" 21 feb 2023 : added a Personal Tab, where we can place stuff we want to keep as long as we wish (backup patterns etc...) Note: the content of this Tab will not be cleared by the button "Clear" (great !) which will clear all the rest. This Tab is a sort of personal backup saved between sessions in the ini file. Its content will never interfere with StringRegExp Results. Changed version from "2.5i" to "2.5j" 20 feb 2023 : added a button to generate AutoIt code in ClipBoard (StringRegExp or StringRegExpReplace). Thanks ioa747 for the suggestion. Ini file contains again binary strings (in case @crlf are found) because IniWrite doesn't accept multi-line values. The GUI could be enlarged or maximized, not shrinked (since version 2.5g) but let's accept to shrink it a bit vertically too Checked exact include files needed (no more, no less) Changed version from "2.5h" to "2.5i" 14 feb 2023 : minor revision, e.g. no need of 2 include files GuiTab.au3 and GuiEdit.au3, because : _GUICtrlTab_GetCurSel() is no more used in code since version 2.5g (included) GUICtrlSendMsg($ebTest, $EM_LIMITTEXT, -1, 0) does the job, instead of _GUICtrlEdit_SetLimitText($ebTest, -1) which used $EM_SETLIMITTEXT msdn : "the EM_SETLIMITTEXT message is identical to the EM_LIMITTEXT message" Changed version from "2.5g" to "2.5h" 12 feb 2023 : added GUI style $WS_SIZEBOX Registered WM_GETMINMAXINFO to prevent shrinking the GUI (it can be enlarged or maximized, not shrinked) Changed the resizing method of the Tab Control to $GUI_DOCKAUTO (thanks Nine & mistersquirrle for resizing help) Deleted the (now) useless code from version 2.5f which allowed to perform an... ...accurate checking of right-click coords inside the edit box of the Search Pattern Tab to display the context menu (when GUI is maximized). Changed version from "2.5f" to "2.5g" 10 jan 2023 : Added $bTab_3IsHighlited to highlight Tab 3 ("ResultSuffix") when "its" edit control $ebResultSuffix contains something. This Tab 3 ("ResultSuffix") may be not as useful as Tab 2 ("ResultPrefix") which was added on 25 dec 2022, but who knows ? Accurate checking of right-click coords inside the edit box of the Search Pattern Tab to display the context menu (when GUI is maximized) Changed version from "2.5e" to "2.5f" 6 jan 2023 : the annoying @CRLF at the end of the Result edit control has been removed (it's safer to see the very exact content, especially when there are spaces at the end of the result, no need of a disturbing superfluous @CRLF) Changed version from "2.5d" to "2.5e" 28 dec 2022 : no more Binary in .ini file (mikell's suggestion) "Replace Pattern" reminder: to replace all matches with an empty string, just indicate a non existing match group, ex. $99 ++++++++++++++++++++++++++ Changed version from "2.5c" to "2.5d" 25 dec 2022 : in main loop, no need to call RegExpExecute() if $nMsg = -11 ($GUI_EVENT_MOUSEMOVE = -11) Added $bTab_1IsHighlited to highlight Tab 1 ("Replace Pattern") when "its" edit control $ebRegExpReplace contains something. Added $bTab_2IsHighlited to highlight Tab 2 ("ResultPrefix") when "its" edit control $ebResultPrefix contains something. Save content of new edit control "Result Prefix" as Binary into ini file (see note dated 29 nov 2018 above) Cosmetic changes (for example added the useful $TCS_FOCUSONBUTTONDOWN style) Changed version from "2.5b" to "2.5c" 2 feb 2021 : Changed GUICtrlSendMsg($ebRegExp, 0x00C2, 0, ...) to GUICtrlSendMsg($ebRegExp, 0x00C2, 1, ...) ; 0x00C2 = $EM_REPLACESEL , 1 (or True) = allow Undo (MSDN) 2 jun 2020 : Added in the script " - Result length: " & StringLen($sResult) 19 jun 2019 : Added "positive lookbehind" and "negative lookbehind" to context menu. Added \R to context menu, i.e any newline sequence (@CRLF, @CR, @LF) 20 feb 2019 : deleted dozens of variables names during context menu creation, see notes below, just before creating the context menu Added "positive lookahead" and "negative lookahead" to context menu. 26 dec 2018 : replaced GUICtrlSendMsg($ebTest, $EM_LIMITTEXT, -1, 0) from 5 nov 2018, with _GUICtrlEdit_SetLimitText($ebTest, -1) 13 dec 2018 : added variable $hDummycontext used for function _TrackPopupMenu() : no need to redefine it at each right click, once is ok delete 3 handles used in Func WM_COMMAND() : control id's do the same job 2 dec 2018 : trying mLipok's Func WM_COMMAND to prevent CPU overheat : don't execute RegExpExecute() constantly, only if changes in GUI (test on $nMsg) or if changes are done "live" in 3 Edit controls (test on $_g_bWasAChange = True in Func WM_COMMAND() 1 dec 2018 : if GUI is maximized, then right click behavior (to display context help menu) is a bit different in Search Pattern Tab As coordinates of Search Pattern Tab has "changed" when GUI is maximized, we will display help context menu in more cases : look at the $WIN_STATE_MAXIMIZED part in script. 30 nov 2018 : changed trigger mouse button for context menu for regexp's help syntax : from "04" (middle button) to "02" right button. Note : Lazycat's Func _IsPressed($nKey) is no more needed because $aInfo[3] = 1 does the same job for testing right click ! So now if you want to copy the regexp part, it wont work with right click. Select it with mouse, then ctrl-c : ok ! 29 nov 2018 : write "match text" edit control content in a separate txt file in plain text (too big now for ini file), not in binary. Binary stays in ini file (for Pattern and Replace) to take care of silly CR in Pattern or Replace edit controls 28 nov 2018 : drag & drop a txt file's content into Edit control, seems to work ! 27 nov 2018 : changed Dummy label control to 1 pixel size ! (used for right click context help menu) 13 nov 2018 : changed Lazycat's 2 Checkbox by 2 Button (wondering why he choosed Checkbox instead of Button) Added $ES_READONLY to Result Editbox (so had to add $WS_HSCROLL too, to stay compatible with Lazycat's special output in this Editbox) Because of $ES_READONLY, had to add $WS_TABSTOP too (more enjoyable when tabbing) 10 nov 2018 : Delete the function _EditReplaceSel() , keeping only 1 line of it in main script ! After that change, insertion (copied from context menu) can be done at 1st position 07 nov 2018 : changed fonts in several places (not very important) moved Gui code lines to allow using Tab correctly between fields 05 nov 2018 : added line GUICtrlSendMsg($ebTest, $EM_LIMITTEXT, -1, 0) it allows to paste a text to check > 30.000 characters (native limit of Edit control) msdn "If cchMax is set to -1, the multiline edit control limit is 0x7FFFFFFE" i.e 2.147.483.646 characters !https://www.autoitscript.com/forum/topic/187377-guictrlcreateedit/https://msdn.microsoft.com/en-us/library/ms908364.aspx Edited March 27, 2023 by pixelsearch Update to version 2.5p Link to comment Share on other sites More sharing options...
ptrex Posted February 14, 2023 Share Posted February 14, 2023 @pixelsearch Regex is a powerful tool. I've been trying to wrap my head around it for along time, but never succeeded properly 😞 Do you have any good tips to get this to a descent level to understand the syntax properly ... Contributions :Firewall Log Analyzer for XP - Creating COM objects without a need of DLL's - UPnP support in AU3Crystal Reports Viewer - PDFCreator in AutoIT - Duplicate File FinderSQLite3 Database functionality - USB Monitoring - Reading Excel using SQLRun Au3 as a Windows Service - File Monitor - Embedded Flash PlayerDynamic Functions - Control Panel Applets - Digital Signing Code - Excel Grid In AutoIT - Constants for Special Folders in WindowsRead data from Any Windows Edit Control - SOAP and Web Services in AutoIT - Barcode Printing Using PS - AU3 on LightTD WebserverMS LogParser SQL Engine in AutoIT - ImageMagick Image Processing - Converter @ Dec - Hex - Bin -Email Address Encoder - MSI Editor - SNMP - MIB ProtocolFinancial Functions UDF - Set ACL Permissions - Syntax HighLighter for AU3ADOR.RecordSet approach - Real OCR - HTTP Disk - PDF Reader Personal Worldclock - MS Indexing Engine - Printing ControlsGuiListView - Navigation (break the 4000 Limit barrier) - Registration Free COM DLL Distribution - Update - WinRM SMART Analysis - COM Object Browser - Excel PivotTable Object - VLC Media Player - Windows LogOnOff Gui -Extract Data from Outlook to Word & Excel - Analyze Event ID 4226 - DotNet Compiler Wrapper - Powershell_COM - New Link to comment Share on other sites More sharing options...
SOLVE-SMART Posted February 14, 2023 Share Posted February 14, 2023 I realized @ptrex, you ask @pixelsearch for tips, but I want to share my experience on getting more familiar with RegEx: I used interactive tutorials in the past like this one for example (which works pretty well for me). Maybe this also fits your personal learning type?! Best regards Sven Stay innovative! Spoiler 🌍 Au3Forums 🎲 AutoIt (en) Cheat Sheet 📊 AutoIt limits/defaults 💎 Code Katas: [...] (comming soon) 🎭 Collection of GitHub users with AutoIt projects 🐞 False-Positives 🔮 Me on GitHub 💬 Opinion about new forum sub category 📑 UDF wiki list ✂ VSCode-AutoItSnippets 📑 WebDriver FAQs 👨🏫 WebDriver Tutorial (coming soon) Link to comment Share on other sites More sharing options...
ptrex Posted February 14, 2023 Share Posted February 14, 2023 @SOLVE-SMART Thanks for the tip ! Any help is welcome 👍 Contributions :Firewall Log Analyzer for XP - Creating COM objects without a need of DLL's - UPnP support in AU3Crystal Reports Viewer - PDFCreator in AutoIT - Duplicate File FinderSQLite3 Database functionality - USB Monitoring - Reading Excel using SQLRun Au3 as a Windows Service - File Monitor - Embedded Flash PlayerDynamic Functions - Control Panel Applets - Digital Signing Code - Excel Grid In AutoIT - Constants for Special Folders in WindowsRead data from Any Windows Edit Control - SOAP and Web Services in AutoIT - Barcode Printing Using PS - AU3 on LightTD WebserverMS LogParser SQL Engine in AutoIT - ImageMagick Image Processing - Converter @ Dec - Hex - Bin -Email Address Encoder - MSI Editor - SNMP - MIB ProtocolFinancial Functions UDF - Set ACL Permissions - Syntax HighLighter for AU3ADOR.RecordSet approach - Real OCR - HTTP Disk - PDF Reader Personal Worldclock - MS Indexing Engine - Printing ControlsGuiListView - Navigation (break the 4000 Limit barrier) - Registration Free COM DLL Distribution - Update - WinRM SMART Analysis - COM Object Browser - Excel PivotTable Object - VLC Media Player - Windows LogOnOff Gui -Extract Data from Outlook to Word & Excel - Analyze Event ID 4226 - DotNet Compiler Wrapper - Powershell_COM - New Link to comment Share on other sites More sharing options...
pixelsearch Posted February 14, 2023 Author Share Posted February 14, 2023 10 hours ago, ptrex said: Do you have any good tips to get this to a descent level to understand the syntax properly ... Hi @ptrex I got a book named "Regular Expressions - The Complete Tutorial" by Jan Goyvaerts. You can easily find it on the web (it's a pdf file, 921Kb) . I consult it from time to time, but not as often as I should. The script above has been revised today from version 2.5g to 2.5h, it's just a minor revision. Link to comment Share on other sites More sharing options...
ioa747 Posted February 15, 2023 Share Posted February 15, 2023 (edited) @pixelsearch Well done, your tool is very good, especially (and not only) for beginners. With the guide on the right click, it guides you briefly, and explains what the symbols do. Congratulations ! if i could suggest, since I see that there is a position available on the right of the tabs. or a hole between the buttons to give the complete code, for copying in the form (ready for delivery) #include <Debug.au3> Local $sRegex = '"data":"([^"]+)"' Local $sString = '[[{"records":{"data":"random data"}}],[{"filtered":{"data":"unknown variable"}}],[{"duplicate":{"data":"not constant"}}],{"subject":"Test"}]' Local $aArray = StringRegExp($sString, $sRegex, 3) _DebugArrayDisplay($aArray) Edited April 26, 2023 by ioa747 pixelsearch and Zedna 2 I know that I know nothing Link to comment Share on other sites More sharing options...
pixelsearch Posted February 16, 2023 Author Share Posted February 16, 2023 4 hours ago, ioa747 said: if i could suggest [...] to give the complete code, for copying in the form (ready for delivery) Thanks for the idea (and your encouragements) A button to generate the whole code would be nice (copying it to ClipBoard) We'll have to think about what to do if the "Replace Pattern" Tab is filled (and then maybe the "Replace count" field too). In this case, a StringRegExpReplace() function should be generated and not a StringRegExp() and its _ArrayDisplay() function etc... I'll think of it when I got some free time (this week being busy) ioa747 1 Link to comment Share on other sites More sharing options...
kut0 Posted February 16, 2023 Share Posted February 16, 2023 and nơ you can try chatGPT to do it, but thank you so much Link to comment Share on other sites More sharing options...
pixelsearch Posted February 20, 2023 Author Share Posted February 20, 2023 @ioa747 Following your suggestion, I added a couple of functions to generate the AutoIt code, it seems to work fine. 2 cases may appear when you click on the "Code" button : 1) StringRegExp code : 2) StringRegExpReplace code. In this example the 'Replace Pattern' Tab contains $2.$1.$3 (surrounded with 1 space) In both pics above, the GUI is vertically shrinked (on purpose) just to reduce the uploaded pics size on the Forum (the regular vertical size is the one found in the pic in 1st post). This new version is named "RegExpQuickTester 2.5i.au3" and its listing is found in 1st post. Link to comment Share on other sites More sharing options...
ioa747 Posted February 20, 2023 Share Posted February 20, 2023 @pixelsearch 👍 what can i say, once again amazing, i already have it hanging in my toolbox Congratulations ! I know that I know nothing Link to comment Share on other sites More sharing options...
pixelsearch Posted February 20, 2023 Author Share Posted February 20, 2023 (edited) Thanks ! I got something to modify : in Mode 0, StringRegExp won't return an Array but an Int32 Gonna fix it this evening and modify the listing accordingly (without changing version) Edit: fixed Edited February 20, 2023 by pixelsearch Link to comment Share on other sites More sharing options...
pixelsearch Posted February 21, 2023 Author Share Posted February 21, 2023 On 2/15/2023 at 9:32 PM, ioa747 said: I see that there is a position available on the right of the tabs. Well... maybe we can fill it with a Personal Tab. In this Tab, we can place stuff we want to keep as long as we wish (alternative patterns etc...) it's a sort of personal backup saved between sessions in the ini file. This Tab content will never interfere with StringRegExp Results. If you guys think it's interesting, then I'll add it in the code. Have a great day ioa747 1 Link to comment Share on other sites More sharing options...
ioa747 Posted February 21, 2023 Share Posted February 21, 2023 (edited) something like favorite patterns I like it ! 👍 PS I have found three link that I think are worth sharing with all off you https://regex101.com/ https://medium.com/factory-mind/regex-tutorial-a-simple-cheatsheet-by-examples-649dc1c3f285 https://medium.com/factory-mind/regex-cookbook-most-wanted-regex-aa721558c3c1 Edited February 21, 2023 by ioa747 I know that I know nothing Link to comment Share on other sites More sharing options...
pixelsearch Posted February 21, 2023 Author Share Posted February 21, 2023 Added the Personal Tab discussed just above. New version 2.5j (listing in 1st post) Link to comment Share on other sites More sharing options...
Sascha Posted February 21, 2023 Share Posted February 21, 2023 I immediately loved it more then my old regexp tester. Good job. Realy usefull. Thanks. Link to comment Share on other sites More sharing options...
pixelsearch Posted February 21, 2023 Author Share Posted February 21, 2023 (edited) 9 hours ago, Sascha said: I immediately loved it I understand this, as I had the very same feeling when discovering this wonderful piece of software back in 2018. Lazycat, w0uter and @steve8tchreally did a great job at the time. Just a minor change I just made, inside the main While...WEnd loop : GUICtrlSetState($ebRegExp, $GUI_FOCUS) commented out, changed to : ; GUICtrlSetState($ebRegExp, $GUI_FOCUS) ; better caret position when line commented out. If someone uses the special context menu to paste anything from the menu, then the caret will be placed just after what has been pasted (when the line is commented out), I like this behavior. On the contrary, when the line is uncommented, then the caret will be placed at the end of the pattern after the paste process has ended (though I saw the caret also placed anywhere in the pattern too, when the line is uncommented) Anyway no big deal, it's just a minor cosmetic change. Uncommented line or commented out, to each his own Edited February 21, 2023 by pixelsearch Link to comment Share on other sites More sharing options...
Lion66 Posted March 15, 2023 Share Posted March 15, 2023 Hi pixelsearch Since I very rarely use regular expressions, I am too lazy to learn this topic. 🙂 But looking at such wonderful programs as this, I always dreamed of a lazy version. This is when I could enter "match text" and "result", and get "pattern". Is it possible? Link to comment Share on other sites More sharing options...
pixelsearch Posted March 15, 2023 Author Share Posted March 15, 2023 2 hours ago, Lion66 said: I could enter "match text" and "result", and get "pattern". A kind of "reverse engineering" I don't know if it's possible, maybe one of our RegEx gurus will SOLVE-SMART 1 Link to comment Share on other sites More sharing options...
pixelsearch Posted March 27, 2023 Author Share Posted March 27, 2023 Updated to version 2.5p (script found in 1st post) . Revisions are : 25 mar 2023 : save & reload 5 Edit Tabs content with UTF-8 (to take care of Unicode characters) Context menu reworked with new items added, also context menu is now prepared in a separate function _PrepareContextMenu() Newlines (@CRLF and/or @LF and/or @CR) correctly parsed & copied in clipboard, e.g. Code button (for pasting directly in Scite) Ready : generated code > 4095 characters split in lines length acceptable by Scite, e.g < 4096 char) Display 'next offset' (e.g. @extended) for RegEx mode 1 & 2 when successful Changed version from "2.5j" to "2.5p" Thanks to @mikell for his advices while I was modifying the context menu Musashi 1 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now