 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
pokercurious
Joined: 16 Dec 2007 Posts: 48
|
Posted: Sun May 25, 2008 3:00 am Post subject: AHK Regex SandBox |
|
|
I'm no AHK genius, but I've put together a little script for playing with regular expressions that may be useful to some people.
Basically, I got tired of creating a new AHK script every time I wanted to test a regex, so I wrote this.
A picture's worth a thousand words, so:
Just start entering in the regex and the search text - it updates as you type.
ALT-C copies the AHK code text for the current RegExMatch or RegExReplace to the clipboard.
And that's it! Quick, dirty, and simple. Any constructive feedback, suggestions, etc. are certainly welcomed and appreciated.
Oh, almost forgot - credit where credit is due. I use Lexikos' ListGlobalVars() function (link to the thread is in the script) to manage RegExMatch's output array. Afaik, the function is magic, and I'm glad that I could harness it's mysterious power.
7.20.08: Tiny script edit to deal with bug if match was exactly "0". Be warned, if your regex is looking for "©¥®©¥®©¥®©¥®", you will not find it. This is now a known issue, and frankly, I'm ok with it.
RegexSandbox.ahk:
| Code: | ;========================+
; Auto-Execution Section |
;==============================================================================
#NoEnv
#SingleInstance force
Sendmode Input
CreateMainGUI()
Return
;==============================================================================
;=========+
; HotKeys |
;==============================================================================
#IfWinActive AHK Regex Sandbox
!c::
Gui, Submit, NoHide
clipboard := (tabselection = "RegExMatch") ? mahkcode : rahkcode
return
;==============================================================================
;========================+
; RegExMatch Subroutines |
;==============================================================================
RegExMatchEval:
Gui, Submit, NoHide
; Clear all variables prefixed with "mre_"
ClearArray("mre_")
; Set non-empty defaults
mstartpos := mstartpos ? mstartpos : 1
; Do RegExMatch
mfoundpos := RegExMatch(mhaystack, mneedle, mre_, mstartpos)
Gosub, DisplayRegExMatchResults
Gosub, DisplayRegExMatchCode
return
DisplayRegExMatchResults:
moutput := "ErrorLevel: " . ErrorLevel . "`n"
. "FoundPos: " . mfoundpos . "`n"
mre_list := GetNonEmptyArrayVars("mre_")
If moutputvar
{
Loop, parse, mre_list, `,
{
moutput .= moutputvar . Substr(A_LoopField, 5) . ": """ . %A_LoopField% . """`n"
}
}
GuiControl, , mresults, %moutput%
return
DisplayRegExMatchCode:
regexmatchcode := "FoundPos := RegExMatch(""" . mhaystack . """, """ . mneedle . """"
If moutputvar
regexmatchcode .= ", " . moutputvar
If mstartpos != 1
regexmatchcode .= (moutputvar ? "" : ", ") . ", " . mstartpos
regexmatchcode .= ")"
GuiControl, , mahkcode, %regexmatchcode%
return
;==============================================================================
;==========================+
; RegExReplace Subroutines |
;==============================================================================
RegExReplaceEval:
Gui, Submit, NoHide
; Set non-empty defaults
rstartpos := rstartpos ? rstartpos : 1
rlimit := rlimit ? rlimit : -1
; Do RegExReplace
rnewstr := RegExReplace(rhaystack, rneedle, rreplacementtext, rcount, rlimit, rstartpos)
Gosub, DisplayRegExReplaceResults
Gosub, DisplayRegExReplaceCode
return
DisplayRegExReplaceResults:
routput := "ErrorLevel: " . ErrorLevel . "`n"
If routputvar
routput .= routputvar . ": " . rcount . "`n"
routput .= "NewStr: " . rnewstr . "`n"
GuiControl, , rresults, %routput%
return
DisplayRegExReplaceCode:
regexreplacecode := "NewStr := RegExReplace(""" . rhaystack . """, """ . rneedle . """"
If (rreplacementtext) or (routputvar) or (rlimit != -1) or (rstartpos != 1)
regexreplacecode .= ", " . ( rreplacementtext ? """" . rreplacementtext . """" : "" )
If routputvar or (rlimit != -1) or (rstartpos != 1)
regexreplacecode .= ", " . ( routputvar ? routputvar : "" )
If (rlimit != -1) or (rstartpos != 1)
regexreplacecode .= ", " . ( (rlimit != -1) ? rlimit : "" )
If (rstartpos != 1)
regexreplacecode .= ", " . rstartpos
regexreplacecode .= ")"
GuiControl, , rahkcode, %regexreplacecode%
return
;==============================================================================
;========================+
; Array-helper functions |
;==============================================================================
ClearArray(prefix)
{
global
lgv := ListGlobalVars()
Loop, parse, lgv, |
{
If (InStr(A_LoopField, prefix) = 1)
%A_LoopField% = ©¥®©¥®©¥®©¥®
}
}
GetNonEmptyArrayVars(prefix)
{
global
local varlist =
lgv := ListGlobalVars()
Loop, parse, lgv, |
{
If (InStr(A_LoopField, prefix) = 1) and (%A_LoopField% != "©¥®©¥®©¥®©¥®")
varlist .= A_LoopField . ","
}
StringTrimRight, varlist, varlist, 1
return varlist
}
;==============================================================================
;===========+
; GUI Stuff |
;==============================================================================
CreateMainGUI()
{
global
Gui, Add, Tab, x2 y2 w500 h500 +Theme vtabselection -background, RegExMatch|RegExReplace
Gui, Tab, RegExMatch
Gui, Font
Gui, Add, Text, x12 y42 w480 h15 +Backgroundtrans, Regular Expression (the "needle"):
Gui, Add, Text, x12 y97 w235 h15 +Backgroundtrans, Output Variable (defaults to ""):
Gui, Add, Text, x257 y97 w235 h15 +Backgroundtrans, Starting Position (defaults to 1):
Gui, Add, Text, x12 y152 w480 h15 +Backgroundtrans, Text to be searched (the "haystack"):
Gui, Add, Text, x12 y257 w480 h15 +Backgroundtrans, Results:
Gui, Add, Text, x12 y457 w480 h15 +Backgroundtrans, AHK Code:
Gui, Font, s10, courier new
Gui, Add, Edit, x12 y57 w480 h30 -VScroll vmneedle gRegExMatchEval,
Gui, Add, Edit, x12 y112 w230 h30 -VScroll vmoutputvar gRegExMatchEval, match
Gui, Add, Edit, x257 y112 w235 h30 -VScroll vmstartpos gRegExMatchEval,
Gui, Add, Edit, x12 y167 w480 h80 vmhaystack gRegExMatchEval,
Gui, Add, Edit, x12 y272 w480 h175 vmresults +readonly,
Gui, Font, s8, courier new
Gui, Add, Edit, x12 y472 w480 h20 vmahkcode +readonly
Gui, Tab, RegExReplace
Gui, Font
Gui, Add, Text, x12 y42 w480 h15 +Backgroundtrans, Regular Expression (the "needle"):
Gui, Add, Text, x12 y97 w150 h15 +Backgroundtrans, Replacement Text (""):
Gui, Add, Text, x172 y97 w150 h15 +Backgroundtrans, Output Variable (""):
Gui, Add, Text, x332 y97 w75 h15 +Backgroundtrans, Limit (-1):
Gui, Add, Text, x417 y97 w75 h15 +Backgroundtrans, Startpos (1):
Gui, Add, Text, x12 y152 w480 h15 +Backgroundtrans, Text to be searched (the "haystack"):
Gui, Add, Text, x12 y257 w480 h15 +Backgroundtrans, Results:
Gui, Add, Text, x12 y457 w480 h15 +Backgroundtrans, AHK Code:
Gui, Font, s10, courier new
Gui, Add, Edit, x12 y57 w480 h30 -VScroll vrneedle gRegExReplaceEval,
Gui, Add, Edit, x12 y112 w150 h30 -VScroll vrreplacementtext gRegExReplaceEval,
Gui, Add, Edit, x172 y112 w150 h30 -VScroll vroutputvar gRegExReplaceEval, count
Gui, Add, Edit, x332 y112 w75 h30 -VScroll vrlimit gRegExReplaceEval,
Gui, Add, Edit, x417 y112 w75 h30 -VScroll vrstartpos gRegExReplaceEval,
Gui, Add, Edit, x12 y167 w480 h80 vrhaystack gRegExReplaceEval,
Gui, Add, Edit, x12 y272 w480 h175 vrresults +readonly,
Gui, Font, s8, courier new
Gui, Add, Edit, x12 y472 w480 h20 vrahkcode +readonly
; (mostly) generated using SmartGUI Creator 4.0
Gui, Show, xCenter yCenter h504 w504, AHK Regex Sandbox
}
GuiEscape:
GuiClose:
ExitApp
;==============================================================================
;==================+
; ListGlobalVars() |
; by Lexikos +====================================+
; http://www.autohotkey.com/forum/viewtopic.php?t=22692 |
;==============================================================================
ListGlobalVars()
{
static hwnd, hwndEdit, pSFW, pSW, bkpSFW, bkpSW
if !hwndEdit
{
dhw := A_DetectHiddenWindows
DetectHiddenWindows, On
Process, Exist
hwnd := WinExist("ahk_class AutoHotkey ahk_pid " ErrorLevel)
ControlGet, hwndEdit, Hwnd,, Edit1
DetectHiddenWindows, %dhw%
hmod := DllCall("GetModuleHandle", "str", "user32.dll")
pSFW := DllCall("GetProcAddress", "uint", hmod, "str", "SetForegroundWindow")
pSW := DllCall("GetProcAddress", "uint", hmod, "str", "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")
}
NumPut(0x0004C200000001B8, pSFW+0, 0, "int64") ; return TRUE
, NumPut(0x0008C200000001B8, pSW+0, 0, "int64") ; return TRUE
, DllCall("SendMessage", "uint", hwnd, "uint", 0x111, "uint", 65407, "uint", 0)
, NumPut(bkpSFW, pSFW+0, 0, "int64")
, NumPut(bkpSW, pSW+0, 0, "int64")
ControlGetText, text,, ahk_id %hwndEdit%
RegExMatch(text, "sm)(?<=^Global Variables \(alphabetical\)`r`n-{50}`r`n).*", text)
pos = 1
Loop {
pos := RegExMatch(text, "m)^[\w#@$?\[\]]+(?=\[\d+ of \d+\]: )", var, pos)
if ! pos
break
list .= var "|"
pos += StrLen(var)
}
return SubStr(list, 1, -1)
}
;============================================================================== |
Last edited by pokercurious on Mon Mar 09, 2009 3:43 am; edited 3 times in total |
|
| Back to top |
|
 |
Thrawn
Joined: 12 May 2008 Posts: 30 Location: Germany
|
Posted: Sun May 25, 2008 3:34 am Post subject: |
|
|
i like
thx a lot  |
|
| Back to top |
|
 |
heresy
Joined: 11 Mar 2008 Posts: 291
|
Posted: Sun May 25, 2008 3:54 am Post subject: |
|
|
i like it though there were already few regex testers
and i like the style how you organized codes very readable
thanks for sharing! _________________ Easy WinAPI - Dive into Windows API World
Benchmark your AutoHotkey skills at PlayAHK.com |
|
| Back to top |
|
 |
trik
Joined: 15 Jul 2007 Posts: 1320
|
Posted: Sun May 25, 2008 4:01 am Post subject: |
|
|
Yeah, there is one. Titan made it. It can be found Here. _________________ Religion is false. >_> |
|
| Back to top |
|
 |
pokercurious
Joined: 16 Dec 2007 Posts: 48
|
Posted: Sun May 25, 2008 4:19 am Post subject: |
|
|
@Ian:
Yeah, I've seen that. I feel like my script serves a different purpose than that one. I wanted to keep my script simple and basic - Titan's does some really cool things that, frankly, kind of scare me =). I only wish my brain worked at that speed.
Anyway, I had a need, wrote a script to fill that need, and thought it was reasonably decent enough to share.
@Thrawn & @heresy:
Thanks for the kind words! |
|
| Back to top |
|
 |
Guest
|
Posted: Sun May 25, 2008 4:36 am Post subject: |
|
|
| actually there's one almost exactly like this already, made by toralf. Found here |
|
| Back to top |
|
 |
pokercurious
Joined: 16 Dec 2007 Posts: 48
|
Posted: Sun May 25, 2008 5:06 am Post subject: |
|
|
| Anonymous wrote: | | actually there's one almost exactly like this already, made by toralf. Found here |
Yeah, I just found that as well.
It's actually interesting because of how different his code is when compared to mine.
Oh well, apologies for duplicating work. I still had fun making it.
Heh, I'm about to update my script with the +theme and +backgroundtrans suggestions from that other thread. It'll at least look a little prettier now. |
|
| Back to top |
|
 |
Guest
|
Posted: Sun May 25, 2008 5:12 am Post subject: |
|
|
the more the better, don't care about duplication notice
and yours has a bit more intuitive gui imo so keep it going
greetz |
|
| Back to top |
|
 |
toralf n-l-i Guest
|
Posted: Mon May 26, 2008 8:00 am Post subject: |
|
|
Hi pokercurious,
Congrats to your script. Don't appologize for your work. If there are more versions for the same purpose, people have a choice and we all have an opportunity to learn.
Thanks
toralf |
|
| Back to top |
|
 |
pokercurious
Joined: 16 Dec 2007 Posts: 48
|
Posted: Mon May 26, 2008 12:14 pm Post subject: |
|
|
| toralf n-l-i wrote: | Hi pokercurious,
Congrats to your script. Don't appologize for your work. If there are more versions for the same purpose, people have a choice and we all have an opportunity to learn.
Thanks
toralf |
=) Thanks. |
|
| Back to top |
|
 |
tank
Joined: 21 Dec 2007 Posts: 3700 Location: Louisville KY USA
|
Posted: Fri May 30, 2008 2:47 pm Post subject: |
|
|
with al programing there are lots of ways to do anything if nothing else if gives people a way to compare different methods and thereby understand whats actually hapening _________________
We are troubled on every side‚ yet not distressed; we are perplexed‚
but not in despair; Persecuted‚ but not forsaken; cast down‚ but not destroyed; |
|
| Back to top |
|
 |
tcgbp
Joined: 04 Apr 2008 Posts: 24 Location: China
|
Posted: Fri Jun 27, 2008 7:10 pm Post subject: |
|
|
| Thrawn wrote: | i like
thx a lot  | me too great work! |
|
| Back to top |
|
 |
ani1744 Guest
|
Posted: Sat Jul 19, 2008 9:45 am Post subject: |
|
|
Awsome program!
But the script has small problem.
Looks like a bug to me.
 |
|
| Back to top |
|
 |
Guest
|
Posted: Sat Jul 19, 2008 10:16 am Post subject: |
|
|
Not a bug (except pehaps in your understanding of regex).
\d find the first digit |
|
| Back to top |
|
 |
pokercurious
Joined: 16 Dec 2007 Posts: 48
|
Posted: Sun Jul 20, 2008 10:58 pm Post subject: |
|
|
@Guest and @ani1744:
It was actually a bug (if ani1744's example was a bit different):
With the needle being "(\d)" and the haystack "R01234.n", the "match1" variable should be set to "0". And it wasn't doing that, because when it checks the array for variables, it was checking for existence, and "0" evaluates to false, and then it wouldn't display the result.
Edit: it was actually a bug in ani1744's example, because the variable "match" should have been "0". my bad. Anyway, fixed below (more or less).
So, I added some screwy ASCII characters to the code that checks for existence:
| Code: | ;========================+
; Array-helper functions |
;==============================================================================
ClearArray(prefix)
{
global
lgv := ListGlobalVars()
Loop, parse, lgv, |
{
If (InStr(A_LoopField, prefix) = 1)
%A_LoopField% = ©¥®©¥®©¥®©¥®
}
}
GetNonEmptyArrayVars(prefix)
{
global
local varlist =
lgv := ListGlobalVars()
Loop, parse, lgv, |
{
If (InStr(A_LoopField, prefix) = 1) and (%A_LoopField% != "©¥®©¥®©¥®©¥®")
varlist .= A_LoopField . ","
}
StringTrimRight, varlist, varlist, 1
return varlist
}
;============================================================================== |
I've updated the script in the inital post to reflect this, and added a warning that if your regex match is exactly "©¥®©¥®©¥®©¥®", then this script will give you kooky results. Yeah, it's inelegant, and I might try to figure out a better solution later, but for now, I'm completely ok with this.  |
|
| 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
|