AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

[func] ValidVarName( ) - will this dbl reference error?

 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
infogulch



Joined: 27 Mar 2008
Posts: 184

PostPosted: Thu Sep 11, 2008 7:03 pm    Post subject: [func] ValidVarName( ) - will this dbl reference error? Reply with quote

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
*/

_________________
A great Beginner's Tutorial
Back to top
View user's profile Send private message
[VxE]



Joined: 07 Oct 2006
Posts: 1496

PostPosted: Thu Sep 11, 2008 10:11 pm    Post subject: Reply with quote

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
}

_________________
My Home Thread
More Common Answers: [1]. It's in the FAQ [2]. Ternary ( a ? b : c ) guide [3]. Post code inside [code][/code] tags !
Back to top
View user's profile Send private message
Titan



Joined: 11 Aug 2004
Posts: 5390
Location: /b/

PostPosted: Thu Sep 11, 2008 10:52 pm    Post subject: Reply with quote

You can also use regex:

Introduction to Variables wrote:
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

_________________

Back to top
View user's profile Send private message Visit poster's website
Krogdor



Joined: 18 Apr 2008
Posts: 1145
Location: The Interwebs

PostPosted: Fri Sep 12, 2008 1:06 am    Post subject: Reply with quote

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

_________________
PlayAHK! Try it out Very Happy
Back to top
View user's profile Send private message AIM Address
Lexikos



Joined: 17 Oct 2006
Posts: 2737
Location: Australia, Qld

PostPosted: Fri Sep 12, 2008 10:02 am    Post subject: Reply with quote

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. Razz
Back to top
View user's profile Send private message
Titan



Joined: 11 Aug 2004
Posts: 5390
Location: /b/

PostPosted: Fri Sep 12, 2008 12:19 pm    Post subject: Reply with quote

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.
_________________

Back to top
View user's profile Send private message Visit poster's website
Lexikos



Joined: 17 Oct 2006
Posts: 2737
Location: Australia, Qld

PostPosted: Fri Sep 12, 2008 12:47 pm    Post subject: Reply with quote

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.
Back to top
View user's profile Send private message
Laszlo



Joined: 14 Feb 2005
Posts: 4078
Location: Pittsburgh

PostPosted: Fri Sep 12, 2008 4:07 pm    Post subject: Reply with quote

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.
Back to top
View user's profile Send private message
infogulch



Joined: 27 Mar 2008
Posts: 184

PostPosted: Sat Sep 13, 2008 7:29 pm    Post subject: Reply with quote

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. Shocked

Smile
_________________
A great Beginner's Tutorial
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Page 1 of 1

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group