AutoHotkey Expression Examples: "" %% () and all that.
because I can never get them right, so I made this. These are all working examples. Version 1.21c 08/24/2009
CONTENTS:
A: | RETRIEVING COMMAND LINE PARAMETERS |
B: | COMMON THINGS AT THE BEGINNING AND END OF AUTOHOTKEY SCRIPTS |
C: | WHEN TO USE %% AROUND VARIABLES |
D: | ERASE A VARIABLE |
E: | SET A VARIABLE := [store numbers, quoted strings] |
F: | SET A VARIABLE = [assign unquoted literal strings] |
G: | COPY A VARIABLE |
H: | IF STATEMENTS with () |
| H2: Comparing Numeric Values vs. Comparing Strings |
I: | IF STATEMENTS without () [Translate the 1st, take the 2nd literally] |
| I2: Comparing Numeric Values vs. Comparing Strings |
J: | CHECK FOR A BLANK VARIABLE |
K: | STRING MANIPULATION
| K1: | Trim whitespace at the start of the string |
| K2: | Trim whitespace at the end of the string |
| K3: | Trim whitespace at the start and the end of the string |
| K4: | Concatenate two strings together
| | K5: | Two ways of using MsgBox |
|
L: | NUMBERS
L1: | Adding numbers together |
L2: | Adding two strings together:
when both can be interpreted as integers, gives the resulting integer (as a string)
when both can be interpreted as float, gives the resulting float (as a string)
when one or both can NOT be interpreted as a number, result is an empty string |
L3: | Remove leading and trailing blanks and leading zeros from a number |
L4: | Various ways to pad a number with leading zeros or spaces |
|
M: | working with FILE NAMES |
N: | REGULAR EXPRESSIONS
N1: | Links to: Cheat Sheets, documentation, programs, libraries |
N2: | Examples |
N3: | RegExReplace
N3.1: Examples |
N3.2: Extract Month, Day, Year, from 1/22/2009 |
N3.3: An example of how we can step by step build up our Regular Expression |
N3.4: Find the $ dollar sign. Extract price and add a dollar sign. |
|
|
O: | MISC AUTOHOTKEY NOTES. CAVEATS & DEBUGGING TIPS
O1: | Notes / Caveats |
O2: | Sending debug data to a log file |
O3: | Capturing a screen image during run |
|
P: | MISC AUTOHOTKEY SCRIPTS
| P1: | Misc AutoHotkey Scripts |
| P2: | Index of notable scripts found in the AutoHotkey Forum |
| P3: | AHK Functions - ƒ() |
| P4: | Library for Text File Manipulation |
| P5: | Tray Icons
| | P6: | Force Exit another AutoHotkey script |
|
Q: | NAVIGATING WEB SITES
Q1: | Determining when a webpage has finished loading |
Q2: | Positioning on a control |
Q3: | Search for a certain colored pixel |
|
R: | NEWBIE RECOMMENDED LEARNING SEQUENCE |
S: | Press ESC to cancel this scipt |
T: | THE AUTOHOTKEY RUN COMMAND |
U: | PASSING PARAMETERS TO AUTOHOTKEY SCRIPTS |
V: | PASSING PARAMETERS TO ANY PROGRAM |
/******************************************************************************
NOTE: |
ALL VARIABLES ARE STORED AS CHARACTER STRINGS !!!
Strings containing numbers are converted to numbers when needed, and the result is converted back to a string.
|
/****************************************************************************** |
NOTE: |
Closing */ must be first thing on line. Otherwise you'll be asking yourself,
"Why does my script stop running at this point, as if the whole rest of
the script was commented out?"
|
/******************************************************************************
A:
- Arguments are delimited by white space, which is either a space or a tab.
- The caret character (^) is not recognized as an escape character or delimiter. The character is handled completely by the command-line parser in the operating system before being passed to the argv array in the program.
- A string surrounded by double quotation marks ("string") is interpreted as a single argument, regardless of white space contained within. A quoted string can be embedded in an argument.
- A double quotation mark preceded by a backslash (\") is interpreted as a literal double quotation mark character (").
- Backslashes are interpreted literally, unless they immediately precede a double quotation mark.
- If an even number of backslashes is followed by a double quotation mark, one backslash is placed in the argv array for every pair of backslashes, and the double quotation mark is interpreted as a string delimiter.
- If an odd number of backslashes is followed by a double quotation mark, one backslash is placed in the argv array for every pair of backslashes, and the double quotation mark is "escaped" by the remaining backslash, causing a literal double quotation mark (") to be placed in argv.
A:
NumParams = %0%
Param1 = %1%
Param2 = %2%
Param3 = %3%
MsgBox NumParams = %0%
MsgBox Param1 = %1%
MsgBox Param2 = %2%
MsgBox Param3 = %3%
/******************************************************************************
B:
#NoTrayIcon ;if you don't want a tray icon for this AutoHotkey program.
#NoEnv ;Recommended for performance and compatibility with future AutoHotkey releases.
#SingleInstance force ;Skips the dialog box and replaces the old instance automatically
;;SendMode Input ;I discovered this causes MouseMove to jump as if Speed was 0. (was Recommended for new scripts due to its superior speed and reliability.)
SetKeyDelay, 90 ;Any number you want (milliseconds)
CoordMode,Mouse,Screen ;Initial state is Relative
CoordMode,Pixel,Screen ;Initial state is Relative. Frustration awaits if you set Mouse to Screen and then use GetPixelColor because you forgot this line. There are separate ones for: Mouse, Pixel, ToolTip, Menu, Caret
MouseGetPos, xpos, ypos ;Save initial position of mouse
WinGet, SavedWinId, ID, A ;Save our current active window
;Set Up a Log File:
SetWorkingDir, %A_ScriptDir% ;Set default directory to where this script file is located. (Note %% because it's expecting and unquoted string)
LogFile := "MyLog.txt"
FileAppend, This is a message`n, %LogFile% ;Note the trailing (`n) to start a new line. This could instead be a leading (`n) if you want. (Note %% because it's expecting and unquoted string)
and things at the end where we restore window and mouse cursor position:
WinActivate ahk_id %SavedWinId% ;Restore original window
MouseMove, xpos, ypos, 10 ;Restore original mouse position
ExitApp
Esc::ExitApp ;Press ESC to cancel this script. Placed after the ExitApp.
;Note this is a hotkey definition (we're defining the ESC key to run ExitApp). A
;hotkey definition line stops execution at that point, so if you want the script
;to run to the end but have the ESC key available to terminate the script, put
;the hotkey definition at the end, just after your ExitApp statement.
/******************************************************************************
C:
LESSON #1:
The only place to use %x% is where a literal string NOT enclosed in
double-quotes is expected. Otherwise, don't use %% around a variable name.
Notice in the following examples that unquoted literal strings are expected.
( = assigns unquoted literal strings )
n = Ishmael
x = Call me %n%
MsgBox %x%
x = 500
y = 500
z = 10
MouseMove, 500, 500, 10 ;works
MouseMove, 500 - 1, 500 + 1, 10 ;works
MouseMove, x, y, z ;works
MouseMove, x - 1, y + 1, z + 2 ;works
;However, this doesn't work, because MouseMove
;doesn't expect an unquoted literal string
MouseMove, %x% - 1, %y% + 1, 10 ;doesn't work
Confusion is caused because the following also happens to work:
MouseMove, %x%, %y%, %c% ;works because "for backward compatibility, command parameters that are
;documented as 'can be an expression' treat an isolated name in percent signs
;(e.g. %Var%, but not Array%i%) as though the percent signs are absent."
; --AutoHotkey Documentation: Variables and Expressions
LESSON #2:
Use (%x%) (enclosed in parentheses) when x contains the name of a 2nd variable which in turn contains the contents you want.
a = 500 ;a = "500"
b = 200 ;b = "200"
x := "a"
y := "b"
MouseMove, (%x%), (%y%) ;x = a, a = 500. y = b, b = 200
MouseGetPos, xpos, ypos
MsgBox xpos=%xpos% ypos=%ypos% ;xpos=500 ypos=200
LESSON #3:
Instances which look like exceptions to the rule:
MyDocument := "C:\Program Files\AutoHotkey\license.txt"
Run, notepad.exe "%MyDocument%"
Looks like we're using %% inside a quoted string,
but actually the "" are not required, just recommended.
This happens to also work:
Run, notepad.exe %MyDocument%
The run function expects an unquoted string, so we use %%,
otherwise notepad would try to open a file named 'MyDocument'.
In the first case above, the run function is actually accepting an unquoted
string which happens to begin and end with a double quote character.
Tech Note
I believe the Target string in the AutoHotkey Run command is passed as the
command_line parameter to the Windows CreateProcess() function. I see in AutoHotkey
source file script.cpp routine Script::ActionExec the call to CreateProcess is:
if (CreateProcess(NULL, command_line, NULL, NULL, FALSE, 0, NULL, aWorkingDir, &si, &pi))
MSDN documentaion for CreateProcess says, "If you are using a long file name that contains a space,
use quoted strings to indicate where the file name ends and the arguments begin."
So the beginning and ending double quote characters are actually a part of the string being passed.
(05/29/2009 — I'm testing how AutoHotkey parses the Run command. I'll post the results when I'm done.)
Reference:
CreateProcess() : http://msdn.microsoft.com/en-us/library/ms682425.aspx
CreateProcess() : http://msdn.microsoft.com/en-us/library/ms682425(VS.85).aspx
|
/******************************************************************************
D:
v =
v := ""
/******************************************************************************
E:
Use the colon-equal operator (:=) for storing numbers and quoted strings
NOTE: All variables including numbers are stored as character strings.
Strings are automatically converted to numbers when necessary,
then converted back to strings when result is stored in a variable.
ABC := "David"
David := "Susan"
v := "ABC" ; v = "ABC"
MsgBox v := "ABC"`n`nv = "%v%"
v := ABC ; ABC is a variable. v = "David"
MsgBox v := ABC`n`nv = "%v%"
v := %ABC% ; ABC is a variable containing the name of a variable. v = "Susan"
MsgBox v := `%ABC`%`n`nv="%v%" ; NOTE: If ABC is undefined or blank, program halts!
v := "123" ; v = "123" (quotes NOT included)
MsgBox v := "123"`n`nv = "%v%"
v := 123 ; v = "123" (If it can be interpreted as a number then it's a number, otherwise it's a variable name.)
MsgBox v := 123`n`nv = "%v%"
;123 can be made into a variable, as in this horrendous example:
123 := 456
MsgBox v = %123% ; message is "v = 456"
/******************************************************************************
F:
equal sign operator (=) to assign unquoted literal strings
To include variable ABC instead of literal string "ABC", use %ABC%
ABC = David
David = Susan
v = 123 ;v = "123"
MsgBox v = 123`n`nv = "%v%"
v = 0001 ;v = "0001"
MsgBox v = 0001`n`nv = "%v%"
v = ABC ;v = "ABC"
MsgBox v = ABC`n`nv = "%v%"
v = %ABC% ;ABC is a variable. v = "David"
MsgBox v = `%ABC`%`n`nv = "%v%" (ABC = "David")
;PROBABLY NOT WHAT YOU WANTED:
v = "ABC" ;v = the literal string "ABC" (including double-quotes)
MsgBox v = "ABC"`n`nv = '%v%'
/******************************************************************************
G:
ABC := "David"
David := "Susan"
v := ABC ; ABC is a variable. v = "David"
MsgBox v := ABC`n`nv = "%v%"
v = %ABC% ; ABC is a variable. v = "David"
MsgBox v = `%ABC`%`n`nv = "%v%"
;PROBABLY NOT WHAT YOU WANTED:
v = ABC ; v = "ABC" (the literal string)
MsgBox v = ABC`n`nv = "%v%"
v := %ABC% ; ABC is a variable containing the name of a variable. v = "Susan"
MsgBox v := `%ABC`%`n`nv="%v%" ; NOTE: If ABC is undefined, PROGRAM HALTS!
(If David is undefined, then v = "")
/******************************************************************************
H:
SAT := "Saturday" ;Another way to view this is:
Saturday := "Saturn" ; SAT --> Saturday --> Saturn
MON := "Monday" ; MON --> Monday --> Moon
Monday := "Moon"
MsgBox SAT := "Saturday"`nSaturday := "Saturn"`nMON := "Monday"`nMonday := "Moon"`n`n(another way to view this:)`nSAT --> Saturday --> Saturn`nMON --> Monday --> Moon`n`n#16
; =
If ("Saturday" = "Saturday")
MsgBox ("Saturday" = "Saturday")
If ("Saturday" = "SATURDAY")
MsgBox ("Saturday" = "SATURDAY")
; == (case sensitive compare)
If ("Saturday" == "Saturday") ;== Case Sensitive
MsgBox ("Saturday" == "Saturday")
If ("Saturday" == "SATURDAY") ;== Case Sensitive
MsgBox NO
;SAT = "Saturday"
If (SAT = "Saturday") ;SAT = "Saturday", compare with "Saturday"
MsgBox (SAT = "Saturday")
If ("Saturday" = SAT) ;Reverse works the same
MsgBox ("Saturday" = SAT)
If (SAT = "xxxxx")
MsgBox NO
If ("xxxxx" = SAT)
MsgBox NO
;%SAT% = "Saturn"
If ("Saturn" = "Saturn")
MsgBox ("Saturn" = "Saturn")
If (%SAT% = "Saturn") ;SAT = "Saturday", %SAT% = "Saturn", compare with "Saturn" (no problem if SAT not defined)
MsgBox (`%SAT`% = "Saturn")`n`n(no problem if SAT not defined)
If ("Saturn" = %SAT%) ;Reverse works the same (no problem if SAT not defined)
MsgBox ("Saturn" = `%SAT`%)`n`n(no problem if SAT not defined)
If ("xxxxx" = %SAT%) ;compare "xxxxx" with "Saturn"
MsgBox NO
If (%SAT% = "xxxxx") ;compare "Saturn" with "xxxxx"
MsgBox NO
;"Moon" = %MON%
If ("Moon" = "Moon")
MsgBox ("Moon" = "Moon")
If (%MON% = "Moon") ;MON = "Monday", Monday = "Moon", compare with "Moon" (no problem if MON not defined)
MsgBox (%MON% = "Moon")`n`nMON = "Monday", Monday = "Moon", compare with "Moon"`n`n(no problem if MON not defined)
If ("Moon" = %MON%) ;"Moon", compare with MON = "Monday", Monday = "Moon" (no problem if MON not defined)
MsgBox ("Moon" = `%MON`%)`n`n"Moon", compare with MON = "Monday", Monday = "Moon"`n`n(no problem if MON not defined)
If ("xxxxx" = %MON%) ;compare "xxxxx" with "Moon"
MsgBox NO
If (%MON% = "xxxxx") ;compare "Moon" with "xxxxx"
MsgBox NO
;SAT =? MON
If (SAT = MON) ;Compare "Saturday" = "Monday" [SAT = "Saturday", MON = "Monday"]
MsgBox NO
If (SAT < MON) ;"Saturday" < "Moon"
MsgBox NO
If (SAT > MON) ;"Saturday" > "Moon" [S > M]
MsgBox (SAT > MON)`n`n"Saturday" > "Monday"`n`n[S > M]
;SAT =? %MON%
If (SAT = %MON%) ;Compare "Saturday" = "Moon". [SAT = "Saturday", compare with MON = "Monday", Monday = "Moon"]
MsgBox NO
If (SAT < %MON%) ;"Saturday" < "Moon"
MsgBox NO
If (SAT > %MON%) ;"Saturday" > "Moon" [S > M]
MsgBox (SAT > `%MON`%)`n`n"Saturday" > "Moon" [S > M]`n`nSAT = "%SAT%",`nMON = "%MON%", %MON% = "Moon"
;%SAT% =? MON
If (%SAT% = MON) ;Compare "Saturn" = "Monday". [SAT = "Saturday", Saturday = "Saturn", MON = "Monday"]
MsgBox NO
If (%SAT% < MON) ;"Saturn" < "Monday"
MsgBox NO
If (%SAT% > MON) ;"Saturn" > "Monday" [S > M]
MsgBox (`%SAT`% > MON)`n`nSAT = "Saturday", %SAT% = "Saturn", compare with MON = "Monday"`n`n"Saturn" > "Moon"`n`n[S > M]
;%SAT% =? %MON%
If (%SAT% = %MON%) ;Compare "Saturn" = "Moon". [SAT = "Saturday", Saturday = "Saturn", compare with MON = "Monday", Monday = "Moon"]
MsgBox NO
If (%SAT% < %MON%) ;"Saturn" < "Moon"
MsgBox NO
If (%SAT% > %MON%) ;"Saturn" > "Moon" [S > M]
MsgBox (`%SAT`% > `%MON`%)`n`nSAT = "Saturday", %SAT% = "Saturn", compare with`nMON = "Monday", %MON% = "Moon"`n`n"Saturn" > "Moon"`n`n[S > M]
H2: Comparing Numeric Values vs. Comparing Strings
If they can both be interpreted as numbers, then they are compared as numbers. Otherwise they are compared as strings.
;COMPARING NUMERIC VALUES VS. COMPARING STRINGS if statements with ()
x = 05 ; x = "05"
if (x > 3.14) ; (5 > 3.14) ? Compare numeric values, since both can be interpreted as numeric values.
MsgBox if (x > 3.14)`nwith x = "05"`n`nCompare numeric values, since both "05" and "3.14" can be interpreted as numbers.`n(5 > 3.14) ?`nyes
else
MsgBox xxxxxx
if (x > "3.14") ; ("05" > "3.14") ? Compare strings, since "3.14" is explicitly a string. (The " " around 3.14 say it's a string, not a number, so do a string compare.)
MsgBox xxxxxx
else
MsgBox if (x > "3.14")`nwith x = "05"`n`nCompare strings, since "3.14" is explicitly a string.`nThe " " around "3.14" say it's a string, not a number, so do a string compare.`n("05" > "3.14") ?`n("0" > "3") ?`n(48 > 51) ?`nno
; ASCII table:
; / 47
; 0 48
; 1 49
; 2 50
; 3 51
; 4 52
; 5 53
; 6 54
; 7 55
; 8 56
; 9 57
; : 58
;DEREFERENCE TESTS
y := "x"
;Compare %y% with 3.14
x = 03 ; x = "03"
if (%y% > 3.14) ; (3 > 3.14) ?
MsgBox xxxxxx
else
MsgBox if (`%y`% > 3.14)`nwith y = "x"`nand x = "03"`n`nCompare numeric values, since both "03" and "3.14" can be interpreted as numbers.`n(3 > 3.14) ?`nno
x = 05 ; x = "05"
if (%y% > 3.14) ; (5 > 3.14) ?
MsgBox if (`%y`% > 3.14)`nwith y = "x"`nand x = "05"`n`nCompare numeric values, since both "05" and "3.14" can be interpreted as numbers.`n(5 > 3.14) ?`nyes
else
MsgBox NO
;Compare %y% with "3.14"
x = 03 ; x = "03"
if (%y% > "3.14") ; ("03" > "3.14") ?
MsgBox xxxxxx
else
MsgBox if (`%y`% > "3.14")`nwith y = "x"`nand x = "03"`n`nCompare strings, since "3.14" is explicitly a string.`nThe " " around "3.14" say it's a string, not a number, so do a string compare.`n("03" > "3.14") ?`n("0" > "3") ?`n(48 > 51) ?`nno
x = 05 ; x = "05"
if (%y% > "3.14") ; ("05" > "3.14") ?
MsgBox xxxxxx
else
MsgBox if (`%y`% > "3.14")`nwith y = "x"`nand x = "05"`n`nCompare strings, since "3.14" is explicitly a string.`nThe " " around "3.14" say it's a string, not a number, so do a string compare.`n("05" > "3.14") ?`n("0" > "3") ?`n(48 > 51) ?`nno
x := "/" ; x = "/"
if (%y% > "3.14") ; ("/" > "3.14") ?
MsgBox xxxxxx
else
MsgBox if (`%y`% > "3.14")`nwith y = "x"`nand x = "/"`n`nCompare strings, since "3.14" is explicitly a string.`nThe " " around "3.14" say it's a string, not a number, so do a string compare.`n("/" > "3.14") ?`n("/" > "3") ?`n(47 > 51) ?`nno
x := ":" ; x = ":"
if (%y% > "3.14") ; (":" > "3.14") ?
MsgBox if (`%y`% > "3.14")`nwith y = "x"`nand x = ":"`n`nCompare strings, since "3.14" is explicitly a string.`nThe " " around "3.14" say it's a string, not a number, so do a string compare.`n(":" > "3.14") ?`n(":" > "3") ?`n(58 > 51) ?`nyes
else
MsgBox xxxxxx
/******************************************************************************
I:
Translate the 1st, take the 2nd literally
SAT := "Saturday" ;Another way to view this is:
Saturday := "Saturn" ; SAT --> Saturday --> Saturn
MON := "Monday" ; MON --> Monday --> Moon
Monday := "Moon"
MsgBox SAT := "Saturday"`nSaturday := "Saturn"`nMON := "Monday"`nMonday := "Moon"`n`n(another way to view this:)`nSAT --> Saturday --> Saturn`nMON --> Monday --> Moon
;SAT
; If "Saturday" = .... illegal
If SAT = Saturday ;SAT = "Saturday", compare with "Saturday"
MsgBox If SAT = Saturday`n`nSaturday = Saturday
If SAT = %Saturday% ;SAT = "Saturday", compare with %Saturday% = "Saturn"
MsgBox NO
If SAT = SAT ;SAT = "Saturday", compare with "SAT"
MsgBox NO
If SAT = %SAT% ;SAT = "Saturday", compare with %SAT% = "Saturday"
MsgBox If SAT = `%SAT`%`n`nSaturday = Saturday
;%SAT%
;NOTE: if SAT is undefined or blank, program will halt!
If %SAT% = Saturn ;SAT = "Saturday", Saturday = "Saturn", compare with "Saturn"
MsgBox If `%SAT`% = Saturn`n`nSAT = "%SAT%", `%Saturday`% = %Saturday%, compare with "Saturn"`n`n(Note: if SAT is undefined or blank, program will halt!)
If %SAT% = xxxxx ;SAT = "Saturday", Saturday = "Saturn", compare with "xxxxx"
MsgBox NO
;Saturday
If Saturday = Saturn ;Saturday = "Saturn", compare with "Saturn"
MsgBox Saturday = Saturn`n`nSaturday="%Saturday%",compare with "Saturn"
If Saturday = xxxxx ;Saturday = "Saturn", compare with "xxxxx"
MsgBox NO
;%Saturday%
;NOTE: if SATURDAY is undefined or blank, program will halt!
If %Saturday% = ;Saturday = "Saturn", Saturn = <nothing>, compare with <nothing>
MsgBox If `%Saturday`% = `n`nSaturday=%Saturday%, Saturn=<nothing>, compare with <nothing>`n`n(NOTE: if SATURDAY is undefined or blank, program will halt!)
If %Saturday% = %Saturn% ;Saturday = "Saturn", Saturn = <nothing>, compare with %Saturn% = <nothing> (<nothing> = <nothing>)
MsgBox if `%Saturday`% = `%Saturn`%`n`nSaturday=%Saturday%, Saturn=<nothing>`ncompare with`%Saturn`% = <nothing>`n`n<nothing>=<nothing>
If %Saturday% = xxxxx ;Saturday = "Saturn", Saturn = <nothing>, compare with "xxxxx"
MsgBox NO
If %Saturday% = "" ;Saturday = "Saturn", Saturn = <nothing>, compare with literal two double-quotes (a string containing two characters, both double-quotes)
MsgBox NO
I2: Comparing Numeric Values vs. Comparing Strings
If they can both be interpreted as numbers, then they are compared as numbers. Otherwise they are compared as strings.
I2:
;COMPARING NUMERIC VALUES VS. COMPARING STRINGS if statements without ()
; ASCII table:
; ! 33
; " 34
; # 35
; 0 48
x = 03 ; x = "03"
if x > 3.14 ; 3 > 3.14 (Compare numeric values, since both can be interpreted as numeric values)
MsgBox xxxxxx
else
MsgBox if x > 3.14`nwith x=%x%`n`nCompare numeric values, since both can be interpreted as numeric values`n3 > 3.14 ?`nno
x = 05 ; x = "05"
if x > 3.14 ; 5 > 3.14 (Compare numeric values, since both can be interpreted as numeric values)
MsgBox if x > 3.14`nwith x=%x%`n`nCompare numeric values, since both can be interpreted as numeric values`n5 > 3.14 ?`nyes
else
MsgBox xxxxxx
x = 03 ; x = "03"
if x > "3.14" ; compare string '03' with string '"3.14"' (double quotes are part of the string). Compare ascii 0 in 03 with leading quotation mark in "3.14" (48 > 34 ?) Yes.
MsgBox if x > "3.14"`nwith x=%x%`n`nDouble quotes are part of the string "3.14"`nso string compare 03 with "3.14"`ncompare leading '0' in 03 with leading quotation mark in "3.14"`nascii(0) = 48`nascii(") = 34`n48 > 34 (?)`nyes
else
MsgBox xxxxxx
x = ! ; x = '!' (ascii 33)
if x > "3.14" ;compare string '!' with string '"3.14"' (double quotes are part of the string). Compare ascii ! with leading quotation mark in "3.14" (48 > 34 ?) Yes.
; (! > ")? --> (33 > 34) ? no
MsgBox xxxxxx
else
MsgBox if x > "3.14"`nwith x=%x%`nno`n`ncompare ascii ! with leading quotation mark in "3.14"`nascii(!) = 33`nascii(") = 34`n(33 > 34)?`nno
x = # ; x = '#' (ascii 35)
if x > "3.14" ; (! > ")? --> (35 > 34) ? yes
MsgBox if x > "3.14"`nwith x=%x%`nyes`n`ncompare ascii # with leading quotation mark in "3.14"`nascii(#) = 35`nascii(") = 34`n(35 > 34)?`nyes
else
MsgBox xxxxxx
; ASCII table:
; ! 33
; " 34
; # 35
; 0 48
;DEREFERENCE TESTS
y := "x"
;compare %y% with 3.14
x = 03 ; x = "03"
if %y% > 3.14 ; 3 > 3.14 (?)
MsgBox xxxxxx
else
MsgBox if `%y`% > 3.14`nwith y := "x"`nand x = "03"`n`nCompare numeric values, since both "03" and "3.14" can be interpreted as numbers.`n3 > 3.14 (?)`nno
x = 05 ; x = "05"
if %y% > 3.14 ; 5 > 3.14 (?)
MsgBox if `%y`% > 3.14`nwith y := "x"`nand x = "05"`n`nCompare numeric values, since both "05" and "3.14" can be interpreted as numbers.`n5 > 3.14 (?)`nyes
else
MsgBox xxxxxx
;compare %y% with "3.14"
x = 03 ; x = "03"
if %y% > "3.14" ; Double quotes are part of the string "3.14" so string compare '03' with string '"3.14"'. Compare ascii 0 in 03 with leading quotation mark in "3.14" (48 > 34 ?) Yes.
MsgBox if `%y`% > "3.14"`nwith y := "x"`nand x=%x%`n`nDouble quotes are part of the string "3.14"`nso string compare 03 with "3.14"`ncompare leading '0' in 03 with leading quotation mark in "3.14"`nascii(0) = 48`nascii(") = 34`n48 > 34 (?)`nyes
else
MsgBox xxxxxx
x = ! ; x = '!' (ascii 33)
if x > "3.14" ;Double quotes are part of the string "3.14" so string compare '!' with string '"3.14"'. Compare '!' with leading quotation mark in "3.14" (48 > 34 ?) Yes.
MsgBox xxxxxx
else
MsgBox if `%y`% > "3.14"`nwith y := "x"`nand x=%x%`n`nDouble quotes are part of the string "3.14"`nso string compare ! with "3.14"`ncompare '!' with leading quotation mark in "3.14"`nascii(!) = 33`nascii(") = 34`n33 > 34 (?)`nno
x = # ; x = '#' (ascii 35)
if x > "3.14" ; (! > ")? --> (35 > 34) ? yes
MsgBox if `%y`% > "3.14"`nwith y := "x"`nand x=%x%`n`nDouble quotes are part of the string "3.14"`nso string compare # with "3.14"`ncompare '#' with leading quotation mark in "3.14"`nascii(#) = 35`nascii(") = 34`n35 > 34 (?)`nyes
else
MsgBox xxxxxx
/******************************************************************************
J:
(or undefined variable)
v := ""
If v =
MsgBox v = ""
If (v = "")
MsgBox v = ""
/******************************************************************************
K:
K1: Trim whitespace at the START of a string
;Trim whitespace at the START of a string:
v := " 0001 "
MsgBox v="%v%"
v := RegExReplace( v, "\A\s+" )
MsgBox v="%v%" ;v = "0001 "
K2: Trim whitespace at the END of a string
;Trim whitespace at the END of a string:
v := " 0001 "
MsgBox v="%v%"
v := RegExReplace( v, "\s+\z" )
MsgBox v="%v%" ;v = " 0001"
K3: Trim whitespace at the START AND END of a string
K3a:
;Trim whitespace at the START AND END of a string:
v := " 0001 "
MsgBox v="%v%"
v := RegExReplace( v, "(^\s+)|(\s+$)")
MsgBox v="%v%" ;v = "0001"
K3b:
;Trim whitespace at the START AND END of the string:
v := " 0001 "
MsgBox v="%v%"
v = %v% ;v = "0001" (AutoTrim ON by default)
MsgBox v="%v%"
K4: Concatenate Two Strings Together
;CONCATENATE TWO STRINGS TOGETHER
SAT := "Saturday"
MON := "Monday"
Saturday := "Saturn"
Monday := "Moon"
; using =
v = %SAT%%MON% ; v = "SaturdayMonday"
MsgBox v = "%v%"
; using :=
v := "Saturday" . "Monday" ; v = "SaturdayMonday"
MsgBox v = "%v%"
v := SAT . MON ; v = "SaturdayMonday" (there must be a SPACE before and after dot)
MsgBox v = "%v%"
v := %SAT% . MON ; v = "SaturnMonday"
MsgBox v = "%v%"
v := SAT . %MON% ; v = "SaturdayMoon"
MsgBox v = "%v%"
v := %SAT% . %MON% ; v = "SaturnMoon"
MsgBox v = "%v%"
K5: Two ways of using MsgBox
This is a good place to mention the two ways of using MsgBox:
Msgbox Var = %Var%
; OR
Msgbox % "Var = " . Var
; string-^^^^^^ | ^^^-variable name
; Concatenate
K6:
SEE ALSO:
Library for Text File Manipulation
http://www.autohotkey.net/~heresy/Functions/TXT.ahk
/******************************************************************************
L:
NOTE: All variables are stored as character strings.
Strings are automatically converted to numbers when necessary,
then converted back to strings when result is stored in a variable.
L1: Adding numbers together
;Adding numbers together
v := "123"
v += 1
MsgBox v = "%v%" ; v <- "124"
v := "123"
v := v + 1
MsgBox v = "%v%" ; v <- "124"
;PROBABLY NOT WHAT YOU WANTED:
v = 123 ; v <- "123" (the literal string)
v = v + 1 ; v <- "v + 1" (the literal string)
MsgBox v = "%v%"
L2: Adding two strings together
;Adding two strings together
;when both can be interpreted as integers, gives the resulting integer (as a string)
v1 := 123
v2 := 456
v := v1 + v2 ; v <- "579"
MsgBox v = "%v%"
;when one or both can be interpreted as float, gives the resulting float (as a string)
v1 := 1.23
v2 := 45.6
v := v1 + v2 ; v <- "46.830000"
MsgBox v = "%v%"
;When one or both can NOT be interpreted as a number, result is an empty string
v1 := "123"
v2 := "Susan"
v := v1 + v2 ; v <- "" (empty string)
MsgBox v = "%v%"
L3: Remove leading/trailing blanks/zeros from a number
;Remove leading zeros from a number
v := 0001 ;v = "0001"
v += 0 ;v converted to integer, add zero, convert back to string
MsgBox v = "%v%" ;v = "1" (the literal string "1"
;Remove leading blanks and trailing blanks from a number
v := " 1 "
MsgBox v = "%v%" ;v = " 1 "
v += 0 ;v converted to integer, add zero, convert back to string
MsgBox v = "%v%" ;v = "1" (the literal string "1"
;Remove leading and trailing blanks and leading zeros from a number
v := " 0001 "
MsgBox v = "%v%" ;v = " 0001 "
v += 0 ;v converted to integer, add zero, convert back to string
MsgBox v = "%v%" ;v = "1" (the literal string "1"
;(yea it's all the same. Just do v += 0)
L4: Pad a number with leading zeros or spaces
/************************************************
VARIOUS WAYS TO PAD A NUMBER WITH LEADING ZEROS OR SPACES
(To pad with spaces, substitute spaces for the zeros.)
L4.1: Method #1: SubStr
;PAD A NUMBER WITH LEADING ZEROS OR SPACES — Method #1: SUBSTR
; Documentation on SubStr: "If StartingPos is less than 1, it is
; considered to be an offset from the end of the string. For example, 0
; extracts the last character and -1 extracts the two last characters."
v := 123
;....v....1 ....v....1
v := SubStr("0000000000" . v, -9) ; v = "0000000123"
MsgBox v = "%v%"
v := SubStr("abcdefghij" . v, -9) ; v = "defghij123" (easier to see what's happening)
MsgBox v = "%v%"
L4.2: Method #2: StringRight
;PAD A NUMBER WITH LEADING ZEROS OR SPACES — Method #2: StringRight
v := 123
;....v....1 ....v....1...
v := "0000000000" . v ; v = "0000000000123" ( or could use v = "0000000000"%v% )
StringRight, v, v, 10 ; v = "0000000123"
MsgBox v = "%v%"
L4.3: Method #3: sprintf()
;PAD A NUMBER WITH LEADING ZEROS OR SPACES — Method #3: sprintf()
StrIn := "1234"
size := VarSetCapacity(StrOut, 8) ;want StrOut to hold 8 digits
;pad with zeros
DllCall("msvcrt\sprintf", Str, StrOut, Str, "%08d", "Int", StrIn ) ;pad with zeros
MsgBox, 0, Zeros, size=%size%`nStrIn = %StrIn%`nStrOut = %StrOut% ;StrOut = "00000123"
;pad with blanks
DllCall("msvcrt\sprintf", Str, StrOut, Str, "%8d", "Int", StrIn ) ;pad with blanks
MsgBox, 0, Spaces, size=%size%`nStrIn = %StrIn%`nStrOut = %StrOut% ;StrOut = " 123"
L4.4: Method #4: Prepend leading zeros
;PAD A NUMBER WITH LEADING ZEROS OR SPACES — Method #4: Prepend leading zeros
v = 123
Loop, % 9-StrLen(v) ; (9 for 9 digits total)
v = 0%v% ; OR: v := 0 . v
MsgBox, 0, Zeros, v = "%v%" ; v = "000000123"
;Prepend leading spaces
v = 123
Loop, % 9-StrLen(v) ; (9 for 9 digits & spaces total)
v := A_Space . v ; OR: v := " " . v
MsgBox, 0, Spaces, v = "%v%" ; v = " 123"
L4.5: Method #5: SetFormat
;PAD A NUMBER WITH LEADING ZEROS OR SPACES — Method #5: Using SetFormat
;(Note: Be wary of converting an integer to a float and back to an integer.
; An integer has 32 bits of data, whereas a float has only 27 bits of data.)
v = 1234
SetFormat, Float, 08.0 ; (08 for zero padded 8 digits total, .0 for zero decimal places)
v += 0.0 ; v converted to float, add zero, convert back to string
MsgBox v = %v% ; v = '00001234'
v = 1234
SetFormat, Float, 8.0 ; (8 for space padded 8 digits & spaces total, .0 for zero decimal places)
v += 0.0 ; v converted to float, add zero, convert back to string
MsgBox v = %v% ; v = ' 1234'
/******************************************************************************
M:
;Set/Show Working Directory
SetWorkingDir,%A_ScriptDir%
MsgBox A_WorkingDir=%A_WorkingDir%
;Creating a File (note: directory must exist)
FileAppend, test 10, MyFile10.log ;<WorkingDir>\MyFile10.log
FileAppend, test 11, \MyFile11.log ;C:\MyFile11.log
FileAppend, test 12, SubDir\MyFile12.log ;<WorkingDir>\SubDir\MyFile12.log
FileAppend, test 13, SubDir\\\\\\\\\\\\\MyFile13.log ;<WorkingDir>\SubDir\MyFile13.log Doesn't seem to matter how many extra \
V := "C:\TEMP"
FileAppend, test 14, %V%MyFile14.log ;C:\TEMPMyFile14.log
FileAppend, test 15, %V%\MyFile15.log ;C:\TEMP\MyFile15.log
FileAppend, test 16, %V%\\\\\\\\\\\MyFile16.log ;C:\TEMP\MyFile16.log Doesn't seem to matter how many extra \
FileAppend, test 17, ..\MyFile17.log ;Up one directory from WorkingDir. <WorkingDir-^>\MyFile17.log
MsgBox ErrorLevel=%ErrorLevel% ;FileAppend test for error. 0=SUCCESS, 1=FAIL
/******************************************************************************
N:
(Note: AutoHotkey uses PCRE Perl-compatible format)
N1:
CHEAT SHEETS
Regular Expressions (RegEx) - Quick Reference: http://www.autohotkey.com/docs/misc/RegEx-QuickRef.htm
Regular Expression Cheat Sheet: http://regexlib.com/CheatSheet.aspx
One Page Reference Cheat Sheet: http://www.regular-expressions.info/reference.html
Replacement Text Reference: http://www.regular-expressions.info/refreplace.html
HEAVY DOCUMENTATION
Syntax of regular expressions in Perl: http://search.cpan.org/dist/perl/pod/perlre.pod
Syntax of regular expressions in Perl: http://perldoc.perl.org/perlre.html
Concatenation of the PCRE man pages: http://www.pcre.org/pcre.txt
Perl Compatible Regular Expressions: http://en.wikipedia.org/wiki/PCRE
PROGRAMS
RegExBuddy: http://www.regexbuddy.com ($40) Screenshot: http://www.regexbuddy.com/screen.html
LIBRARIES
Regular Expression Library: http://regexlib.com/
Categories:
- Email
- Uri
- Numbers
- Strings
- Dates and Times
- Misc
- Address/Phone
- Markup/Code
http://www.regular-expressions.info/examples.html
- Grabbing HTML Tags
- Trimming Whitespace
- Matching an IP address
- Matching a Floating Point Number
- Matching an Email Address
- Matching Valid Dates
- Finding or Verifying Credit Card Numbers
- Matching Complete Lines
- Removing Duplicate Lines or Items
- Regex Examples for Processing Source Code
- Two Words Near Each Other
A Collection/Library Of Regular Expressions: http://www.autohotkey.com/forum/viewtopic.php?t=13544
- Ensure that a path doesn't end with a backslash
- Ensure that a path ends with a backslash
- Replace characters illegal in a file name by something else (can be empty)
- Keep only lines starting with a given string
- Parse a date
- trim chars on left and/or right of strings
- How to make parsing loops work from back to front?
- How to replace variable references in a template text file by the value of the referenced variables?
- How to replace i with I only if it has spaces before and after
- remove duplicate lines
N2:
Examples from: http://www.regular-expressions.info/numericranges.html
Matching Floating Point Numbers with a Regular Expression
Here are a few more common ranges that you may want to match:
000..255: —— ^([01][0-9][0-9]|2[0-4][0-9]|25[0-5])$
0 or 000..255: —— ^([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])$
0 or 000..127: —— ^(0?[0-9]?[0-9]|1[0-1][0-9]|12[0-7])$
0..999: —— ^([0-9]|[1-9][0-9]|[1-9][0-9][0-9])$
000..999: —— ^[0-9]{3}$
0 or 000..999: —— ^[0-9]{1,3}$
1..999: —— ^([1-9]|[1-9][0-9]|[1-9][0-9][0-9])$
001..999: —— ^(00[1-9]|0[1-9][0-9]|[1-9][0-9][0-9])$
1 or 001..999: —— ^(0{0,2}[1-9]|0?[1-9][0-9]|[1-9][0-9][0-9])$
0 or 00..59: —— ^[0-5]?[0-9]$
0 or 000..366: —— ^(0?[0-9]?[0-9]|[1-2][0-9][0-9]|3[0-6][0-9]|36[0-6])$
Examples from: http://www.codeproject.com/KB/dotnet/regextutorial.aspx
1. elvis Find elvis
2. \belvis\b Find elvis as a whole word
3. \belvis\b.*\balive\b Find text with "elvis" followed by "alive"
4. \b\d\d\d-\d\d\d\d Find seven-digit phone number
5. \b\d{3}-\d{4} Find seven-digit phone number a better way
6. \ba\w*\b Find words that start with the letter a
7. \d+ Find repeated strings of digits
8. \b\w{6}\b Find six letter words
9. .^\d{3}-\d{4}$ Validate a seven-digit phone number
10. \b\w{5,6}\b Find all five and six letter words
11. \b\d{3}\s\d{3}-\d{4} Find ten digit phone numbers
12. \d{3}-\d{2}-\d{4} Social security number
13. ^\w* The first word in the line or in the text
14. \(?\d{3}[) ]\s?\d{3}[- ]\d{4} A ten digit phone number
15. \S+ All strings that do not contain whitespace characters
16. \b\d{5}-\d{4}\b|\b\d{5}\b Five and nine digit Zip Codes
17. (\(\d{3}\)|\d{3})\s?\d{3}[- ]\d{4} Ten digit phone numbers, a better way.
This expression will find phone numbers in several formats, like
"(800) 325-3535" or "650 555 1212".
The "\(?" searches for zero or one left parentheses,
"[) ]" searches for a right parenthesis or a space. The
"\s?" searches for zero or one whitespace characters.
Unfortunately, it will also find cases like
"650) 555-1212" in which the parenthesis is not balanced.
Below, you'll see how to use alternatives to eliminate this problem.
18. (\d{1,3}\.){3}\d{1,3} A simple IP address finder
19. ((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?) IP finder
20. \b(\w+)\b\s*\1\b Find repeated words
21. \b(?<Word>\w+)\b\s*\k<Word>\b Capture repeated word in a named group
22. \b\w+(?=ing\b) The beginning of words ending with "ing"
23. (?<=\bre)\w+\b The end of words starting with "re"
24. (?<=\d)\d{3}\b Three digits at the end of a word, preceded by a digit
25. (?<=\s)\w+(?=\s) Alphanumeric strings bounded by whitespace
26. \b\w*q[^u]\w*\b Words with "q" followed by NOT "u"
27. \b\w*q(?!u)\w*\b Search for words with "q" not followed by "u"
28. \d{3}(?!\d) Three digits not followed by another digit
29. (?<![a-z ])\w{7} Strings of 7 alphanumerics not preceded by a letter or space
30. (?<=<(\w+)>).*(?=<\/\1>) Text between HTML tags
31. Text between HTML tags (see referenced source page above)
32. a.*b The longest string starting with a and ending with b
33. a.*?b The shortest string starting with a and ending with b
Phone numbers:
a. \(\d\d\d\)\s\d\d\d-\d\d\d\d
b. \(\d{3}\)\s\d{3}-\d{4}
4. \b\d\d\d-\d\d\d\d Find seven-digit phone number
5. \b\d{3}-\d{4} Find seven-digit phone number a better way
9. .^\d{3}-\d{4}$ Validate a seven-digit phone number
11. \b\d{3}\s\d{3}-\d{4} Find ten digit phone numbers
14. \(?\d{3}[) ]\s?\d{3}[- ]\d{4} A ten digit phone number
17. (\(\d{3}\)|\d{3})\s?\d{3}[- ]\d{4} Ten digit phone numbers, a better way.
Dates:
a. (\d\d)-(\d\d)-(\d\d\d\d) MM-DD-YYYY (MM -& $1, DD -& $2, YYY -& $3)
b. (\d\d\d\d)-(\d\d)-(\d\d) YYYY-MM-DD (YYYY -& $1, MM -& $2, DD -& $3)
c. ^\d{1,2}\/\d{1,2}\/\d{4}$ XX/XX/YYYY where XX can be 1 or 2 digits long and YYYY is always 4 digits long.
/******************************************************************************
N3:
N3.1: Basic examples
; Examples
f1 := RegExReplace("55555", "5", "five") ;f1 = "fivefivefivefivefive"
MsgBox f1=%f1%
f2 := RegExReplace("55555", "55", "x") ;f2 = "xx5"
MsgBox f2=%f2%
N3.2: EXTRACT Month, Day, Year, from 1/22/2009
;Regular Expression to EXTRACT Month, Day, Year, from 1/22/2009
;month & day can be 1 or 2 digits
c := "xxxxxxxx 1/22/2009 yyyyyyyyyyyy"
month := RegExReplace(c,".*?(\d{1,2})\/(\d{1,2})\/(\d{4})(.*)","$1")
day := RegExReplace(c,".*?(\d{1,2})\/(\d{1,2})\/(\d{4})(.*)","$2")
year := RegExReplace(c,".*?(\d{1,2})\/(\d{1,2})\/(\d{4})(.*)","$3")
MsgBox month=%month%`nday=%day%`nyear=%year%
N3.3: An example of how we can step by step build up our Regular Expression
;An example of how we can step by step build up our Regular Expression
;Given string c, extract the data...
c := " 02-17-2009 238 Payment by Check. 314.15 9,265.35 "
;Trim leading and trailing spaces
c = %c%
; 1.
; c := "02-17-2009 238 Payment by Check. 314.15 9,265.35"
; Start with "(.*)" which grabs the whole string
f3 := RegExReplace(c, "(.*)", "$1")
MsgBox f3=%f3%
; f3 = "02-17-2009 238 Payment by Check. 314.15 9,265.35"
; 2.
; c := "02-17-2009 238 Payment by Check. 314.15 9,265.35"
; Add "(\d\d)" to parse off the first two digits (the month)
f4 := RegExReplace(c, "(\d\d)(.*)", "{$1} {$2}")
MsgBox f4=%f4%
; f4 = "{02} {-17-2009 238 Payment by Check. 314.15 9,265.35}"
; 3.
; c := "02-17-2009 238 Payment by Check. 314.15 9,265.35"
; Add "-" to parse off the dash
f5 := RegExReplace(c, "(\d\d)-(.*)", "{$1} {$2}")
MsgBox f5=%f5%
; f5 = "{02} {17-2009 238 Payment by Check. 314.15 9,265.35}"
; 4.
; c := "02-17-2009 238 Payment by Check. 314.15 9,265.35"
; Add "(\d\d)" to parse off the second two digits (the day) and save it as $2
f6 := RegExReplace(c, "(\d\d)-(\d\d)(.*)", "{$1} {$2} {$3}")
MsgBox f6=%f6%
; f6 = "{02} {17} {-2009 238 Payment by Check. 314.15 9,265.35}"
; 5.
; c := "02-17-2009 238 Payment by Check. 314.15 9,265.35"
; Add "-" to parse off the dash
f6 := RegExReplace(c, "(\d\d)-(\d\d)(.*)", "{$1} {$2} {$3}")
MsgBox f6=%f6%
; f6 = "{02} {17} {-2009 238 Payment by Check. 314.15 9,265.35}"
; 6.
; c := "02-17-2009 238 Payment by Check. 314.15 9,265.35"
; Add "(\d\d\d\d)" to parse off the year (4 digits) and save it as $3
f7 := RegExReplace(c, "(\d\d)-(\d\d)-(\d\d\d\d)(.*)", "{$1} {$2} {$3} {$4}")
MsgBox f7=%f7%
; f7 = "{02} {17} {2009} { 238 Payment by Check. 314.15 9,265.35}"
; 7.
; c := "02-17-2009 238 Payment by Check. 314.15 9,265.35"
; Add " +" to parse off one or more spaces
f8 := RegExReplace(c, "(\d\d)-(\d\d)-(\d\d\d\d) +(.*)", "{$1} {$2} {$3} {$4}")
MsgBox f8=%f8%
; f8 = "{02} {17} {2009} {238 Payment by Check. 314.15 9,265.35}"
; 8.
; c := "02-17-2009 238 Payment by Check. 314.15 9,265.35"
; Add "(\d+)" to parse off the check number (one or more digits) and save it as $4
f9 := RegExReplace(c, "(\d\d)-(\d\d)-(\d\d\d\d) +(\d+)(.*)", "{$1} {$2} {$3} {$4} {$5}")
MsgBox f9=%f9%
; f9 = "{02} {17} {2009} {238} { Payment by Check. 314.15 9,265.35}"
; 9.
; c := "02-17-2009 238 Payment by Check. 314.15 9,265.35"
; Add " +" to parse off one or more spaces
f10 := RegExReplace(c, "(\d\d)-(\d\d)-(\d\d\d\d) +(\d+) +(.*)", "{$1} {$2} {$3} {$4} {$5}")
MsgBox f10=%f10%
;f10 = "{02} {17} {2009} {238} {Payment by Check. 314.15 9,265.35}"
; 10.
; c := "02-17-2009 238 Payment by Check. 314.15 9,265.35"
; Add "(.*?)" to parse off the text (minimal match), followed by " {5}" to parse off 5 spaces
; (there apparently is always 5 spaces. This tells us when we're done parsing off the text.)
f11 := RegExReplace(c, "(\d\d)-(\d\d)-(\d\d\d\d) +(\d+) +(.*?) {5}(.*)", "{$1} {$2} {$3} {$4} {$5} {$6}")
MsgBox f11=%f11%
; f11 = "{02} {17} {2009} {238} {Payment by Check.} {314.15 9,265.35}"
; 11.
; c := "02-17-2009 238 Payment by Check. 314.15 9,265.35"
; Add "([\d,.]+)" to parse off the dollars and cents (one or more digits with possible commas and decimal point, e.g. 27,182.81)
f12 := RegExReplace(c, "(\d\d)-(\d\d)-(\d\d\d\d) +(\d+) +(.*?) {5}([\d,.]+)(.*)", "{$1} {$2} {$3} {$4} {$5} {$6} {$7}")
MsgBox f12=%f12%
; f12 = "{02} {17} {2009} {238} {Payment by Check.} {314.15} { 9,265.35}"
; 12.
; c := "02-17-2009 238 Payment by Check. 314.15 9,265.35"
; Add " {3}" to parse off 3 spaces (apparently always 3)
f13 := RegExReplace(c, "(\d\d)-(\d\d)-(\d\d\d\d) +(\d+) +(.*?) {5}([\d,.]+) {3}(.*)", "{$1} {$2} {$3} {$4} {$5} {$6} {$7}")
MsgBox f13=%f13% ;f13 = "{02} {17} {2009} {238} {Payment by Check.} {314.15} {9,265.35}"
; 13.
; c := "02-17-2009 238 Payment by Check. 314.15 9,265.35"
; Add "([\d,.]+" to parse off the dollars and cents (one or more digits with possible commas and decimal point, e.g. 27,182.81)
f14 := RegExReplace(c, "(\d\d)-(\d\d)-(\d\d\d\d) +(\d+) +(.*?) {5}([\d,.]+) {3}([\d,.]+)(.*)", "{$1} {$2} {$3} {$4} {$5} {$6} {$7} {$8}")
MsgBox f14=%f14%
; f14 = "{02} {17} {2009} {238} {Payment by Check.} {314.15} {9,265.35} {}"
; (the last empty {} indicates there's nothing left over)
N3.4: Find the $ dollar sign. Extract price and add a $.
;find the $ dollar sign
c := "xxx $17.25 yyy"
dollar := RegExReplace(c,"(.*?)(\$)(.*)","$2")
MsgBox dollar=%dollar%
;extract price and add a dollar sign
c := "xxx 17.25 yyy"
price := RegExReplace(c,"(.*?)([\d,.]+)(.*)","$$$2")
msgbox price=%price% ; price = "$17.25"
; For RegExReplace replace string only:
; To specify a literal $, use $$
; $ is the only character that needs such special treatment in a RegEx replace string.
; Backslashes are never needed to escape anything else in a RegEx replace string.
; (RegEx search string still needs to have many characters escaped.)
/******************************************************************************
O:
O1: Notes / Caveats
|
ALL VARIABLES ARE STORED AS CHARACTER STRINGS !!!
Strings containing numbers are converted to numbers when needed, and the result is converted back to a string.
|
/****************************************************************************** |
|
Closing */ must be first thing on line. Otherwise you'll be asking yourself,
"Why does my script stop running at this point, as if the whole rest of
the script was commented out?"
MsgBox Hello
/* here is a comment
and another comment */
MsgBox Goodbye ;You'll never see this message
MsgBox Hello
/* here is a comment
and another comment
*/
MsgBox Goodbye ;Now you're OK
|
/****************************************************************************** |
|
Space here ruins function call
↓
MyFunc (Param1)
MyFunc(Param1)
|
- When sending text, if there are problems, sometimes it helps to
throw in a short delay (Sleep 100), or to slow down the sending of characters
by using SetKeyDelay (e.g. SetKeyDelay 90)
- MsgBox: You may need to manually restore focus to your current window
after a call to MsgBox. I was debugging an AutoHotkey script by throwing
in a bunch of MsgBox messages, and I discovered a problem that focus
wasn't being returned to my window after the MsgBox timed out. So, I
added a WinActivate after MsgBox to restore focus to my window, and all
was well again.
(May have been caused by cross contamination from
another unrelated program. I'm so tired of debugging Windows programs
only to discover there's nothing wrong with the program I'm debugging, it's the Windows
OS itself that's been corrupted by a completely unrelated program.
I thought those days were long behind us.)
Update: I had another case where this fix was exactly the wrong thing to do.
The "current window" wasn't the one I wanted. Removing the WinExist/WinActivate
combo fixed the problem. (Alas, no solution is universal.)
O2: Sending Debug Data To A Log File
;Example 1. Log a message
SetWorkingDir, %A_ScriptDir% ;Set default directory to where this script file is located
LogFile := "MyLog.txt"
FileAppend, This is a message`n, %LogFile% ;(note the trailing (`n) to start a new line. This could instead be a leading (`n) if you want.
;Example 2. Include a time stamp
SetWorkingDir, %A_ScriptDir% ;Set default directory to where this script file is located
LogFile := "MyLog.txt"
FormatTime, TimeString, , yyyy-MM-dd hh:mm:ss tt
FileAppend, `n%TimeString% : This is a message`n, %LogFile%
;Example 3. Put it all in a function named LogMsg
SetWorkingDir, %A_ScriptDir% ;Set default directory to where this script file is located
LogFile := "MyLog.txt"
LogMsg("This is a message") ;Note LogMsg adds a leading (`n) so each message starts on a new line
LogMsg("Variable X = " . X ) ;Concatenate using the dot .
ExitApp
;---------------------------
;And here is our function:
LogMsg( msg )
{
global LogFile
FormatTime, TimeString, , yyyy-MM-dd hh:mm:ss tt
FileAppend, `n%TimeString% : %msg%, %LogFile%
}
Update: I've had cases where using FileAppend
too frequently causes it to occasionally fail. An expected line in the log file just isn't there.
You can check ErrorLevel, but there's no way to
get further info on why it failed. Tech note: This
may be because FileAppend closes the file every time. That can be a lot of
opening/closing a file.
O3: Capturing a screen image during run using IrfanView
/******************************************************************************
Capturing a screen image during run using IrfanView (www.irfanview.com)
*/
RunWait "C:\Program Files\IrfanView\i_view32.exe" "/capture=1 /convert=C:\TEMP\MyImage.bmp"
/******************************************************************************
P:
P1: Misc AutoHotkey Scripts
P2: Index of notable scripts found in the AutoHotkey Forum : http://www.autohotkey.com/wiki/index.php?title=Script_Listing
- 1 AutoHotkey Related
- 1.1 Ports/custom builds
- 1.1.1 Windows NT+
- 1.1.2 Windows CE
- 1.1.3 Windows/Linux/Mac (.NET/Mono)
- 1.2 Compile AutoHotkey yourself
- 1.2.1 MS Visual C++
- 1.2.2 GCC
- 1.3 Use AutoHotkey with other programming/scripting languages
- 1.4 Use other programming/scripting languages inline in AutoHotkey
- 1.4.1 Perl
- 1.4.2 C#/VB
- 1.4.3 VBScript/JScript, VB/VBA/MS Office
- 1.4.4 Assembly/Machine code
- 1.4.5 C/C++
- 1.4.6 Lisp/ECL
- 1.5 Scripts
- 1.6 Tools
- 1.7 Editors
- 2 GUI
- 2.1 General
- 2.2 All
- 2.3 3P Controls
- 2.4 MsgBox
- 2.5 ListBox
- 2.6 Splash
- 2.7 Menu
- 2.8 Templates
- 2.9 Hotkey
- 2.10 Button
- 2.11 Hyperlink
- 2.12 ListView
- 2.13 Edit
- 2.14 Other
- 2.15 Tooltip
- 2.16 TreeView
- 3 Functions
- 4 Audio and Video
- 5 File Management and Searching
- 6 File Reading & Parsing
- 7 Internet related
- 8 XML, HTML and BBCode
- 9 Window Manipulation
- 10 Keyboard Enhancements
- 11 Mouse Related
- 12 Clipboard Manipulation
- 13 Games
- 14 Fun
- 15 Images
- 16 Time and Scheduling
- 17 Encryption / Encoding / Binary
- 18 System Related
- 19 Security
- 20 Miscellaneous
|
P3: AHK Functions - ƒ()
http://www.autohotkey.com/forum/viewtopic.php?t=8728
- AUTOHOTKEY:
- STRINGS:
- SetWidth(Str,Width,AlignText) - increase a string's length by adding spaces to it and aligns it Left/Center/Right.
- NumFormat( Number, Width, Dec, PadChar ) - format a float. Pad leading characters (any character) to a numeric string.
- Replicate(chr,x)
Replicate(chr(196),80) - creates a horizontal ruling 80 characters wide
- Space(Width)
Space(80) - 80 spaces
- UPPER(String)
- LOWER(String)
- PROPER(String)
http://www.autohotkey.com/forum/viewtopic.php?p=53028#53028
- COLOR:
- HEX2RGB(HEXString,Delimiter="")
- RGB2HEX(RGBString,Delimiter="")
- CheckHexC(HEXString) - validates a "Hex Color Code" by calling the above two functions.
Examples:
HEX2RGB("FFFFFF") -> "255,255,255"
RGB2HEX("255,255,255") -> "FFFFFF"
CheckHexC("FFFFFF") -> 1
CheckHexC("GOYYAH") -> 0
http://www.autohotkey.com/forum/viewtopic.php?p=58125#58125
- FILES:
- SOUND:
- IMAGES:
- VIDEO:
- SYSTEM:
P4: Library for Text File Manipulation : http://www.autohotkey.net/~heresy/Functions/TXT.ahk
- Basic Functions
- TXT_TotalLines
- TXT_ReadLines
- TXT_Tail
- Alignment Functions
- TXT_AlignLeft
- TXT_AlignCenter
- TXT_AlignRight
- TXT_ReverseLines
- Removement Functions
- TXT_RemoveLines
- TXT_RemoveBlankLines
- TXT_RemoveDuplicateLines
- Replacement Functions
- TXT_Replace
- TXT_RegExReplace
- TXT_ReplaceLine
- Insertion Functions
- TXT_LineNumber
- TXT_InsertLine
- TXT_InsertPrefix
- TXT_InsertSuffix
- Column Functions
- TXT_ColGet
- TXT_ColPut
- TXT_ColCut
- Trimming Functions
- TXT_TrimLeft
- TXT_TrimRight
- CSV Functions
- File Join/Split Functions
P5: Tray Icons : http://www.autohotkey.com/wiki/index.php?title=Script_Listing
P6: Force Exit another AutoHotkey script
To force Exit another AutoHotkey script (and have it's icon removed from the system tray):
WM_COMMAND = 0x111
ID_FILE_EXIT = 65405
PostMessage, WM_COMMAND, ID_FILE_EXIT, 0, , <window-title>
Example: To end the DimScreen program (an AutoHotkey script at http://www.donationcoder.com/Software/Skrommel/#DimScreen)
WM_COMMAND = 0x111
ID_FILE_EXIT = 65405
PostMessage, WM_COMMAND, ID_FILE_EXIT, 0, , DimScreen Screen
Notes: The above only works for AutoHotkey scrips (*.ahk, or compiled to *.exe)
Notes: To determine the Window Title, run Process Explorer
Notes: AutoHotkey has the following WM_COMMAND numbers defined in resource.h
ID_FILE_PAUSE | 65403 |
ID_FILE_SUSPEND | 65404 |
ID_FILE_EXIT | 65405 |
(0x111 is WM_COMMAND) |
Tech note: Other WM_COMMAND numbers defined in AutoHotkey source file resource.h
(I haven't tried any of these to see what they do)
ID_FILE_RELOADSCRIPT | 65400 |
ID_FILE_EDITSCRIPT | 65401 |
ID_FILE_WINDOWSPY | 65402 |
ID_FILE_PAUSE | 65403 |
ID_FILE_SUSPEND | 65404 |
ID_FILE_EXIT | 65405 |
ID_VIEW_LINES | 65406 |
ID_VIEW_VARIABLES | 65407 |
ID_VIEW_HOTKEYS | 65408 |
ID_VIEW_KEYHISTORY | 65409 |
ID_VIEW_REFRESH | 65410 |
ID_HELP_USERMANUAL | 65411 |
ID_HELP_WEBSITE | 65412 |
Another way to identify the AutoHotkey script you want to Exit(/Suspend/Pause):
WM_COMMAND = 0x111
ID_FILE_EXIT = 65405
DetectHiddenWindows, On
WinGet, AList, List, ahk_class AutoHotkey ; Make a list of all running AutoHotkey programs
Loop %AList% { ; Loop through the list
ID := AList%A_Index%
WinGetTitle, ATitle, ahk_id %ID% ; (You'll notice this isn't the same 'window title')
MsgBox, 3, %A_ScriptName%, %ATitle%`n`nEnd?
IfMsgBox Cancel
Break
IfMsgBox Yes
PostMessage,WM_COMMAND,ID_FILE_EXIT,0,,% "ahk_id" AList%A_Index% ; End the process (65404 to suspend, 65403 to pause)
}
ExitApp
/******************************************************************************
Q:
See example file WebsiteNav.ahk
Q1: DETERMINING WHEN A WEBPAGE HAS FINISHED LOADING
See FAQ: http://www.autohotkey.com/docs/FAQ.htm#load
Q2: POSITION US ON A CERTAIN CONTROL
Examples are from simple to more complex.
All examples here are demonstrated in file WebsiteNav.ahk
- Method 1: Blindly hit the {Tab} key a certain number of times to position us where we want to be.
(Not very reliable. e.g. User may have Google toolbar installed, which we'd have to tab through.
Or perhaps Yahoo toolbar. Or no toolbar. Who knows...)
Example:
Send {Tab 34} ;say, 34 tabs gets us where we want to be.
- Method 2. Hit the {Tab} key until certain text appears in the status bar
For this example, assume we are at http://www.autohotkey.com/
and we wish to position ourselves on the Wiki link:
; For this example, Tab until we find the autoHotkey "Wiki" link
; When we tab to the AutoHotkey "Wiki" link, the status bar says "http://www.autohotkey.com/wiki/"
target := "http://www.autohotkey.com/wiki/"
loop, 40
{
sleep 10 ;this pause may help
StatusBarGetText, StatBar, , AutoHotkey - Free Mouse and Keyboard Macro Program
if (StatBar = target)
{
goto FOUNDIT
}
Send, {Tab}
}
;If we drop out here, it means we failed to find our target after 40 tabs
MsgBox Failed to find %target%
ExitApp
FOUNDIT:
MsgBox Found target %target%
- Method 2.5 Hit Shift+Tab to tab backwards until certain text appears in the status bar
(May be useful if tabbing forwards doesn't work)
- Method 3. Search for word which is link you want to click on
- Method 4. Jump directly to the control
The JavaScript method—we place some JavaScript code in the address bar and execute it
to jump directly to the control.
This is a faster and more reliable technique, but it's a bit more complicated to set up.
We use AutoHotkey ControlSetText to place the JavaScript code in the address bar,
specifying the HTML control ID, or the control NAME, of the control we want to jump to,
then we use AutoHotkey ControlSend to execute that JavaScript.
For this example, assume we are at http://www.autohotkey.com/wiki/
and we wish to position ourselves in the Search field.
Determine the ID or NAME of the control:
For these examples assume you're at http://www.autohotkey.com/wiki/
- General format using ID:
; Position to a Control Using the Control's Unique ID
ControlSetText, Edit1, javascript:document.getElementById('<element-ID>')[0].focus()
ControlSend, Edit1, {Enter}, <window-title>
Sleep 100 ;give it a moment too do it's thing (important)
(Caution: getElementById is case sensitive! I originally tried getElementByID (last letter D instead of d) and it didn't work.)
Example using ID:
; Position to a Control Using the Control's Unique ID
; For this example the control's ID is searchInput
; and the window title contains the word AutoHotkey
ControlSetText, Edit1, javascript:document.getElementById('searchInput').focus()
ControlSend, Edit1, {Enter}, AutoHotkey
Sleep 100 ;give it a moment too do it's thing (important)
- General format using NAME:
; Position to a Control Using the Control's NAME
ControlSetText, Edit1, javascript:document.getElementsByName('<element-name>')[0].focus()
ControlSend, Edit1, {Enter}, <window-title>
Sleep 100 ;give it a moment too do it's thing (important)
Example using NAME:
; Position to a Control Using the Control's NAME
; For this example the control's NAME is search
; and the window title contains the word AutoHotkey
ControlSetText, Edit1, javascript:document.getElementsByName('search')[0].focus()
ControlSend, Edit1, {Enter}, AutoHotkey
Sleep 100 ;give it a moment too do it's thing (important)
If more than one control has the same name:
- Go kick George Foreman in the shin for naming all 5 of his sons "George" (and two of his daughters).
- Then figure out what number to use instead of [0] to get to the n'th control with that NAME.
(Note: There is no legal way to use the NAME attribute from such tags as DIV or SPAN, according to the W3C HTML 4.01 specs. You must confine the usage of this attribute to such tags as INPUT, IMG, FRAME, IFRAME, FORM, MAP, PARAM, META, OBJECT, A, SELECT, APPLET, TEXTAREA, or BUTTON. (Those who use XML or XHTML or XFILES or whatever may have different rules to play by.)
If the control you want has no ID or NAME:
- Argh! This is getting hard! You'll have to go read up about JavaScript and the DOM (Document Object Model)
Some things you could try:
javascript:document.getElementsByTagName('a')[6].focus() ; Get the 7th <A> tag in the document (numbering begins with 0).
javascript:document.links[6].focus() ; Get the 7th link in the document (numbering begins with 0).
- Methods 5,6,7,...
For more advanced methods see these two posts:
Q3: SEARCH FOR A COLORED PIXEL
Note: If I'm searching a white background for black text, I find it
works better to search for "not white" rather than search for
"black", because sometimes that black text isn't really black
when you look at it closely.
The following actually goes quite fast if you comment out the moving of
the mouse. I move the mouse here for demonstration purposes.
WinGetPos, winposX, winposY, Width, Height, A ;Get window Width, Height
;MsgBox, 0, , winposX=%winposX%`n winposY=%winposY% `nWidth=%Width% `nHeight=%Height%,
;Calculate a starting position
X := Width - 60
Y := Height / 2
MouseMove, X, Y, 7
MsgBox, 0, , Move left until we find "not white", 1.2
;move left until we find "not white"
loop 200
{
MouseMove, X, Y, 0
PixelGetColor, color, X, Y, RGB
;MsgBox, 0, , color=%color%, 0.1
if (color <> "0xFFFFFF")
{
Goto FOUND_TCOLOR
}
X -= 1
}
;If we drop out here, it means we failed to find our target
MsgBox, 0, , Failed to find color "not white", 2
goto Exit
FOUND_TCOLOR:
MsgBox, 0, , Found "not white". color = %color%, 2
Exit:
MsgBox, 0, , The End, 2
ExitApp
/************************************************
R:
Reference: Recommended by jaco0646 (thank you jaco0646)
http://www.autohotkey.com/forum/viewtopic.php?t=29204)
- Commands dealing with files start with FILE
- Commands dealing with windows start with WIN
- Commands dealing with text start with STRING
Similarly:
- Commands that retrieve data from somewhere contain GET
- Commands that apply data to somewhere contain SET
Suggested order of study for AutoHotkey newbies:
First:
- read the Tutorial
- the Scripts page
- the FAQ
Afterwards, recommend learning concepts in the following order:
- Hotstrings
- Hotkeys
- Mouse Clicks & Mouse HotKeys
- Variables
- Loops - especially Parsing Loops
- String commands - (e.g. StringMid, StringReplace)
- If,Else statements
- Expressions
- Arrays & Dynamic variables - (StringSplit)
- GoSub & Functions
- GUIs
- Windows Messages
- DllCall
/******************************************************************************
S:
A hotkey definition line stops execution at that point, so if you want the
script to run to the end but have the ESC key available to terminate the script,
put the hotkey definition at the end, just after your ExitApp statement.
;Press ESC to cancel this script
Esc::ExitApp
/******************************************************************************
T:
Program:
Run, ShowParams.exe hello goodbye Friday
AutoHotkey script:
Run, autohotkey.exe ShowParams.ahk hello goodbye Friday
VBScript:
Run, cscript.exe ShowParams.vbs hello goodbye Friday
JScript:
Run, cscript.exe ShowParams.js hello goodbye Friday
Any command:
┌───── cmd.exe strips off these outer " ───────┐
Run, "%comspec%" /c ""ShowParams.ahk" "hello" "goodbye" "friday"", , Hide
Hide is specified to prevent the Command Prompt Window from popping up.
/c causes Command Prompt Window to exit after command is executed.
/k instead of /c would cause Command Prompt Window to remain open after command is executed. Useful for debugging.
Notes:
An alternative to using Run is to directly call ShellExecute() :
command = ShowParams.ahk
params = hello goodbye Friday
res := DllCall("shell32\ShellExecuteA"
, "UInt", 0 ; hwnd
, "UInt", 0 ; lpOperation
, "Str", command ; lpFile
, "Str", params ; lpParameters
, "Str", A_WorkingDir ; lpDirectory
, "UInt", 0) ; nShowCmd
MsgBox (%ErrorLevel%) %res%
/******************************************************************************
U:
On Windows, parameters are parsed off the command line after the new process is created,
by the new process.
It's considered the responsibility of the newly started application to call the
GetCommandLine()
API to retrieve the command line string and parse it.
How does a C/C++ program on Windows get argv[]?
The C/C++ compiler which compiles the program secretly adds extra
code to the executable that retrieves and parses the command line to extract
the parameters before calling WinMain (or main). Thus, for a C/C++ executable
on Windows, the parameter parsing rules are determined by the C/C++
compiler that compiled the program.
AutoHotkey is written in C++ and obtains its parameters via the argv[]
vector.
Thus it uses the Microsoft C/C++ Parameter Parsing Rules. The rules are:
- Parameters are always separated by a space or tab (multiple spaces/tabs OK)
- If the parameter does not contain any spaces, tabs, or double quotes, then all the characters in the parameter are accepted as is (there is no need to enclose the parameter in double quotes).
- Enclose spaces and tabs in a double quoted part
- A double quoted part can be anywhere within a parameter
- 2n backslashes followed by a " produce n backslashes and start or end a double quoted part
- 2n+1 backslashes followed by a " produce n backslashes + a literal quotation mark
- n backslashes not followed by a quotation mark produce n backslashes
- If a closing " is followed immediately by another ", the 2nd " is accepted literally and added to the parameter (this is the undocumented rule)
For more on passing parameters to programs, with numerous examples, see the essay
How Command Line Parameters Are Parsed
Notes:
/******************************************************************************
V:
You aren't sure how to escape the special characters in that parameter
so it comes out right? See the essay
How Command Line Parameters Are Parsed
/******************************************************************************
My title: "" %% (), And All That, is taken from the wonderful book, Div, Grad, Curl, And All That: An Informal Text on Vector Calculus by H. M. Schey (1973)
History:
Version 1.00 02/28/2009
Version 1.04 03/08/2009
Version 1.05 03/09/2009
Version 1.09 03/26/2009
Version 1.10 04/30/2009
Version 1.12 05/15/2009
Version 1.14 05/24/2009
Version 1.19 06/01/2009
Version 1.21 08/24/2009
Version 1.22 01/02/2011