Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Regex that matches valid Ruby local variable names

Does anyone know the rules for valid Ruby variable names? Can it be matched using a RegEx?

UPDATE: This is what I could come up with so far:

^[_a-z][a-zA-Z0-9_]+$

Does this seem right?

like image 440
kolrie Avatar asked Sep 06 '10 01:09

kolrie


4 Answers

Identifiers are pretty straightforward. They begin with letters or an underscore, and contain letters, underscore and numbers. Local variables can't (or shouldn't?) begin with an uppercase letter, so you could just use a regex like this.

/^[a-z_][a-zA-Z_0-9]*$/
like image 144
AboutRuby Avatar answered Nov 06 '22 21:11

AboutRuby


It's possible for variable names to be unicode letters, in which case most of the existing regexes don't match.

varname = "\u2211" # => "∑" 
eval(varname + '= "Tony the Pony"') => "Tony the Pony"
puts varname # => ∑
local_variable_identifier = /Insert large regular expression here/
varname =~ local_variable_identifier # => nil

See also "Fun with Unicode" in either the Ruby 1.9 Pickaxe or at Fun with Unicode.

like image 37
Andrew Grimm Avatar answered Nov 06 '22 21:11

Andrew Grimm


According to http://rubylearning.com/satishtalim/ruby_names.html a Ruby variable consists of:

A name is an uppercase letter, lowercase letter, or an underscore ("_"), followed by Name characters (this is any combination of upper- and lowercase letters, underscore and digits).

In addition, global variables begin with a dollar sign, instance variables with a single at-sign, and class variables with two at-signs.

A regular expression to match all that would be:

%r{
  (\$|@{1,2})?  # optional leading punctuation
  [A-Za-z_]     # at least one upper case, lower case, or underscore
  [A-Za-z0-9_]* # optional characters (including digits)
}x

Hope that helps.

like image 3
rjk Avatar answered Nov 06 '22 21:11

rjk


I like @aboutruby's answer, but just to complete it, here's the equivalent using POSIX bracket expressions.

/^[_[:lower:]][_[:alnum:]]*$/

Or, since a-z is actually shorter than [:lower:]:

/^[_a-z][_[:alnum:]]*$/
like image 3
kikito Avatar answered Nov 06 '22 21:11

kikito