AutoHotkey Community

It is currently May 26th, 2012, 12:18 pm

All times are UTC [ DST ]




Post new topic Reply to topic  [ 9 posts ] 
Author Message
PostPosted: September 11th, 2008, 8:03 pm 
Offline

Joined: March 27th, 2008, 2:14 pm
Posts: 700
This simple function is a way to check if a string is valid for double referencing, e.g. x := %DblRef?%

There are actually other characters that are valid for a variable name, but this is just by the docs.

I'd welcome anything faster/better!

Code:
ValidVarName( x )
{ ; by Infogulch - http://www.autohotkey.com/forum/viewtopic.php?p=219669#219669
   Loop, Parse, x
   {
      chr:=Asc(A_LoopField)
      If (48 <= chr && chr <= 57)
            || (65 <= chr && chr <= 90)
            || (97 <= chr && chr <= 122)
         Continue
      Else If chr in 35,36,63,64,91,93,94
         Continue
      Else, Return 0
   }
   Return 1
}

/*
Asc values for various characters:

   0-9: 48-57
   A-Z: 65-90
   a-z: 97-122
   # : 35
   $ : 36
   ? : 63
   @ : 64
   [ : 91
   ] : 93
   _ : 94
*/

_________________
Scripts - License


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 11th, 2008, 11:11 pm 
Offline
User avatar

Joined: October 7th, 2006, 8:45 am
Posts: 3329
Location: Simi Valley, CA
There's a validity check in one of my functions... take a look:
Code:
PassGlobal(varname, newvalue="PG_[VxE]_SAYS_NO_NEW_VALUE")
{
   local tempval
   Loop, Parse, varname ; check validity of varname
   If !InStr("1234567890qwertyuiopasdfghjklzxcvbnm#_@$?[]", A_LoopField)
   return "" ; boo hoo... not valid T_T
   tempval := %varname%
   If (newvalue != "PG_[VxE]_SAYS_NO_NEW_VALUE")
      %varname% := newvalue
   return tempval
}


edit: here's a sloppy benchmark script just for comparison:
Code:
SetBatchLines, -1
start := A_TickCount
Loop % 10**6
   bubble := PassGlobal("bubble")
msgbox % "It took " A_TickCount - start "ms to do a million of those."
; tested at 20609 on my machine

start := A_TickCount
Loop % 10**6
   bubble := ValidVarName( "bubble" )
msgbox % "It took " A_TickCount - start "ms to do a million of those."
; tested at 40578 on my machine

ValidVarName( x )
{ ; by Infogulch - http://www.autohotkey.com/forum/viewtopic.php?p=219669#219669
   Loop, Parse, x
   {
      chr:=Asc(A_LoopField)
      If (48 <= chr && chr <= 57)
            || (65 <= chr && chr <= 90)
            || (97 <= chr && chr <= 122)
         Continue
      Else If chr in 35,36,63,64,91,93,94
         Continue
      Else, Return 0
   }
   Return 1
}

/*
Asc values for various characters:

   0-9: 48-57
   A-Z: 65-90
   a-z: 97-122
   # : 35
   $ : 36
   ? : 63
   @ : 64
   [ : 91
   ] : 93
   _ : 94
*/

PassGlobal(varname, newvalue="PG_[VxE]_SAYS_NO_NEW_VALUE")
{
   local tempval
   Loop, Parse, varname ; check validity of varname
   If !InStr("1234567890qwertyuiopasdfghjklzxcvbnm#_@$?[]", A_LoopField)
   return "" ; boo hoo... not valid T_T
   tempval := %varname%
   If (newvalue != "PG_[VxE]_SAYS_NO_NEW_VALUE")
      %varname% := newvalue
   return tempval
}

_________________
Ternary (a ? b : c) guide     TSV Table Manipulation Library
Post code inside [code][/code] tags!


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 11th, 2008, 11:52 pm 
Offline
User avatar

Joined: August 11th, 2004, 1:47 am
Posts: 5347
Location: UK
You can also use regex:

Variable names are not case sensitive (for example, CurrentDate is the same as currentdate). Variable names may be up to 254 characters long and may consist of letters, numbers and the following punctuation: # _ @ $ ? [ ]

Code:
var = myvar123

If (RegExMatch(var, "i)^[a-z\d#_@$?[\]]{1,254}$"))
   MsgBox, is valid
Else MsgBox, not valid

_________________
GitHubScriptsIronAHK Contact by email not private message.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 12th, 2008, 2:06 am 
Offline

Joined: April 18th, 2008, 7:57 am
Posts: 1390
Location: The Interwebs
Took Titan's and added in ~150 more valid characters:

Code:
If (RegExMatch(var, "i)^[\w#@$?[\]`€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ]{1,254}$"))
   MsgBox, is valid
Else MsgBox, not valid


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 12th, 2008, 11:02 am 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7502
Location: Australia
I use the following regular expression:
Code:
[\w#@$?\[\]%\x80-\xFF]{1,254}

Afaik, \x isn't documented, but neither is the validity of the characters I've expressed with it. :P


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 12th, 2008, 1:19 pm 
Offline
User avatar

Joined: August 11th, 2004, 1:47 am
Posts: 5347
Location: UK
Krogdor wrote:
Took Titan's and added in ~150 more valid characters
If you want to be very precise you could also check for reserved A_ variables.

Quote:
I use the following regular expression:
Lexicos your regex fails because it doesn't anchor to the start and end of the stack. I would be cautious of high ASCII chars and different encodings - I haven't studied ahk's source well enough to be sure its reliable.

_________________
GitHubScriptsIronAHK Contact by email not private message.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 12th, 2008, 1:47 pm 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7502
Location: Australia
Titan wrote:
If you want to be very precise you could also check for reserved A_ variables.
There is an optimisation in place that replaces expressions consisting only of a double-deref with a dynamic input variable. A_ variables can be double-derefed in these cases:
Code:
n = A_TickCount
MsgBox % %n% ; works
MsgBox % %n% "" ; doesn't work
Also, if the purpose of validating the name is to avoid a runtime error dialog, there is no need to exclude A_ variables.
Quote:
Lexicos your regex fails because it doesn't anchor to the start and end of the stack.
That depends on what you use the regex for. I use it to find variable names within an expression.
Quote:
I would be cautious of high ASCII chars and different encodings
I wouldn't recommend their use, either, but it is inaccurate to exclude them as valid characters.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 12th, 2008, 5:07 pm 
Offline

Joined: February 14th, 2005, 4:05 pm
Posts: 4710
Location: Boulder, CO
By using other than normal ANSI characters you can have funny looking variables:
Code:
funny variable = ? ; space = ALT 0160, ANSI
MsgBox % funny variable

another one = ! ; space = ALT 255, US codepage
MsgBox % another one

² × ³ = 6
MsgBox %² × ³%
You can find other examples here.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 13th, 2008, 8:29 pm 
Offline

Joined: March 27th, 2008, 2:14 pm
Posts: 700
Thanks for you guy's input!

I'm not surprised my function was so much slower, and I'd like to see some more benchmarking with the RE's. (don't forget the S option) Maybe I'll do it sometime.

It's nice to know what some of those other acceptable characters are, but using spaces is wierd. :shock:

:)

_________________
Scripts - License


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 9 posts ] 

All times are UTC [ DST ]


Who is online

Users browsing this forum: bbwht, oldbrother and 56 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group