A Quick Tip for Matching Something Inside a Variable (AutoHotkey Tip)

With Many If Comparison Commands on the Chopping Block in V2.0, Here’s a Trick for Both AutoHotkey V1.1 and  V2.0

RobotMakeSenseWhile driving with her girls buckled in the back seat of the car, my daughter informed her attentive three-year-old and five-year-old of some important details about the day’s activities. After finishing up her explanation, she asked, “Now, does that make sense?” Both girls responded in unison, “Yes, Mommy!” That seemed to settle things until she overheard the three-year-old while leaning over toward the five-year-old whisper, “That doesn’t make any sense!”

I have no doubt that my blogs from the last number of weeks about how to convert to AutoHotkey V2.0 make many readers feel exactly like my three-year-old granddaughter. “It doesn’t make any sense at all!.” I agree that a person can easily get bogged down in the weeds of AutoHotkey—especially when talking about changing from AutoHotkey version 1.1 to version 2.0. I don’t operate under the illusion that the change to 2.0 will be easy. In fact, I don’t expect a mass rush to the new version. Just like Windows XP, many people will stubbornly hang onto V1.1—and why shouldn’t they.

Library BenefitsAutoHotkey V1.1 works and works well. While I can see advantages to V2.0, I don’t think the average AutoHotkey user needs to worry about switching—at least not for a long time. And, if it doesn’t make any sense to them, they shouldn’t do it! Experienced programmers might make up most of the early adopters of V2.0.

I write about V2.0 to help AutoHotkey users make their decision about which version to use…eventually. (Currently, with AutoHotkey V2.0 in alpha release, I only recommend V1.1, but you can “Fool Around with the New AutoHotkey Version 2.0.”) The day may come when I recommend only V2.0, but that’s a long way off—if ever. People should take the path of least resistance (and least confusion).

This time I offer an AutoHotkey technique which works in both versions. I happened to stumble upon it while working on a V1.1 to V2.0 script conversion.

A Tip for Any Version of AutoHotkey

While working on converting one of my scripts to AutoHotkey V2.0, I chanced upon a secret which anyone can immediately apply to either version of AutoHotkey. (It’s not really a secret, although not well known either.) If I had not been foraging for a V2.0 function comparable to a V1.1 command, I may not have noticed it at all.  I discovered the trick while searching for an If Var Contains List command replacement:

If A_LoopFileAttrib contains H,R,S

While I had no problem finding the built-in A_LoopFileAttrib variable in V2.0, the If Var Contains List command had departed for the nether regions. (Since V2.0 reserves the words Contain and In, the command may return in the future.) The example in the Remarks section below the variable explanation offered an alternative approach to evaluating the contents of the A_LoopFileAttrib variable:

If A_LoopFileAttrib ~= "[HRS]" ; See ~= operator. 
     Continue ; Skip this file and move on to the next one.

What? New to me, this “approximately equal to” operator ~= left me wondering. (To be fair, the ~= operator has been in AutoHotkey since 2009. I just never noticed it before.) I dug a little deeper to uncover the inner workings of this feature.

It turns out that the ~= operator acts as shorthand for the RegExMatch() function in both AutoHotkey V1.1 and V2.0:

RegExMatch(a, b) ⇒ a ~= b

This gives us a quick method for evaluating complex matches using Regular Expressions in either V1.1 or V2.0. Regular Expressions (RegEx) offer much more power than that provided by the If Var Contains List command, but, they can bend your brain. To keep it simple, I offer a couple of functions replacing the If Var Contains List command which anyone can use—no knowledge of how to write Regular Expressions required. Just follow these examples and pretend that they have nothing to do with RegExs.

Note: Regular Expressions can get pretty complicated. You can get a quick start with the AutoHotkey Regular Expression Quick Reference Guide, this introductory RegEx page, or my book A Beginner’s Guide to Using Regular Expressions in AutoHotkey

Since it works in exactly the same manner, you could directly use the RegExMatch() function, but using the shorthand ~= makes you feel like you don’t need to know anything about RegEx—and you don’t!

Match Any Character in a List

In the first example above, If A_LoopFileAttrib ~= “[HRS]”, the RegEx range [HRS] attempts to match any single letter inside the square braces to any character found in the variable A_LoopFileAttrib. If AutoHotkey matches any one of the characters, the expression returns the position of the first value matched. As long as evaluated as non-zero (i.e. a match), the result returns true, skips the current item, and Loops (Continue command) to the next file.

This example code replaces the If Var Contains List command which V2.0 no longer supports.

If you want the expression to not match any of the letters (e.g. no hidden files H, no read-only files R, and no system files S), then you can add a caret inside the square braces (V1.1) and (V2.0):

if A_LoopFileAttrib ~= "[^HRS]" 

In this case, AutoHotkey only matches the RegEx if all of the characters do not appear in the variable. But, that might use too much RegEx. Let’s keep it simple.

Since the a ~= b shortcut actually represents a function, the following also works:

if A_LoopFileAttrib ~= "[HRS]" = 0

No extra RegEx code required!

Matching Strings (Seasons of the Year)

If you want to match one word in a list, then place the vertical line | (which acts as the RegEx connector or) between each string (V1.1):

If A_MMMM ~= "(Dec|Jan|Feb)"
  MsgBox It's Wintertime!
If A_MMMM ~= "(Mar|Apr|May)"
  MsgBox It's Springtime!
If A_MMMM ~= "(Jun|Jul|Aug)"
  MsgBox It's Summertime!
If A_MMMM ~= "(Sep|Oct|Nov)"
  MsgBox It's Autumn!

RegEx returns the position of the first character of the first matched option (the number 1 for the month names) in the A_MMMM current month variable (e.g. February). When you type the Hotstring Sdate, AutoHotkey instantly displays a MsgBox stating the season of the year—just in case you don’t get out much.

Want the negative?

:c*:Ndate:: ; Hotstring for season of the year
If A_MMMM ~= "(Dec|Jan|Feb)" = 0
  MsgBox It's not Wintertime!
If A_MMMM ~= "(Mar|Apr|May)" = 0
  MsgBox It's not Springtime!
If A_MMMM ~= "(Jun|Jul|Aug)" = 0
  MsgBox It's not Summertime!
If A_MMMM ~= "(Sep|Oct|Nov)" = 0
  MsgBox It's not Autumn!

V2.0 Tip: To convert the above code into V2.0 format, you only need to place double-quotation marks around the text in the MsgBox command/function. Everything else works!

The single character match in a range [abc] (or [0-9] for digits one through nine) and the word match (Dec|Jan|Feb) offer simple replacements for the V1.1 If Var Contains List command. These matches work in both versions of AutoHotkey.

Stop here if you don’t want to venture further into the RegEx weeds.

Anyone familiar with Regular Expressions knows that they can get pretty complicated. But, that’s where you find the RegEx power. You can accomplish many difficult tasks not easily completed without them. If you do understand a little bit about how Regular Expressions work, then you can get even fancier.

While I don’t offer a tutorial here, I explain the following RegExs in my book A Beginner’s Guide to Using Regular Expressions in AutoHotkey. However, after one glance, you may decide to sit it out.

Check for E-Mail Address

The following Hotstring Eadd instantly runs a RegEx which checks the Email variable for valid e-mail addresses:

:c*:Eadd:: ; Hotstring for email address
Email := "Jack@ComputorEdge.com"
If Email ~= "\w+([.-]?\w+)*@\w+([.-]?\w+)*(\.\w{2,4})"
  MsgBox E-mail Yes!
  MsgBox E-mail No! 

You can use this RegEx in an AutoHotkey form to ensure the user enters a proper e-mail address.

Check for IP Address

Not a complete validation, this Hotstring IP address format checker IPck only looks for the three dots and up to three digits in each field:

:c*:IPck:: ; Hotstring for email address
IP := ""
If IP ~= "(\d{1,3}\.){3}\d{1,3}"
  MsgBox IP Format Yes!
  MsgBox IP Format No!

If you want to make sure you have a valid IP address (i.e. numbers within the ranges 0-255), then you will find a much longer RegEx which does the job in the Beginner’s AutoHotkey Regular Expression book.

The shorthand ~= for the RegExMatch() function does everything you need to replace the If Var Contains List command plus a lot more. You only need either the range [abc] or the word either/or options (word1|word2|word3) examples as replacement code.



Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s