> I have need of some code to match any of a number of words in any =
number
> of characters from the beginning of the word between the smallest =
number
> of characters that will uniquely identify it and the total number of
> characters in the word.  My solution so far has been a set of kind of
> ugly, but conceptually simple, regular expressions:

There is nothing "kind of ugly" about it and it doesn't "work fine". The =
regexps are _very_ ugly and as you can see below, they're ugly enough =
that it is hard to see that they're wrong and fit to match a lot more =
than they should. I edit one step at a time and describe each step above =
the method.

# original - flog: 35.1
def expand_attribute_arg1(attr)
  if attr.to_s.downcase.match(
    /^s[t]?[r]?[e]?[n]?[g]?[t]?[h]?$/
  )
    return 'Strength'
  elsif attr.to_s.downcase.match(
    /^d[e]?[x]?[t]?[e]?[r]?[i]?[t]?[y]?$/
  )
    return 'Dexterity'
  elsif attr.to_s.downcase.match(
    /^co[n]?[s]?[t]?[i]?[t]?[u]?[t]?[i]?[o]?[n]?$/
  )
    return 'Constitution'
  elsif attr.to_s.downcase.match(
    /^i[n]?[t]?[e]?[l]?[l]?[i]?[g]?[e]?[n]?[c]?[e]?$/
  )
    return 'Intelligence'
  elsif attr.to_s.downcase.match(
    /^w[i]?[s]?[d]?[o]?[m]?$/
  )
    return 'Wisdom'
  elsif attr.to_s.downcase.match(
    /^ch[a]?[r]?[i]?[s]?[m]?[a]?$/
  )
    return 'Charisma'
  else
    puts "#{attr} is an invalid attribute value."
    exit(1)
  end
end

# remove stupid formatting and align - flog: 35.1
def expand_attribute_arg2(attr)
  if    attr.to_s.downcase.match /^s[t]?[r]?[e]?[n]?[g]?[t]?[h]?$/
    return 'Strength'
  elsif attr.to_s.downcase.match /^d[e]?[x]?[t]?[e]?[r]?[i]?[t]?[y]?$/
    return 'Dexterity'
  elsif attr.to_s.downcase.match =
/^co[n]?[s]?[t]?[i]?[t]?[u]?[t]?[i]?[o]?[n]?$/
    return 'Constitution'
  elsif attr.to_s.downcase.match =
/^i[n]?[t]?[e]?[l]?[l]?[i]?[g]?[e]?[n]?[c]?[e]?$/
    return 'Intelligence'
  elsif attr.to_s.downcase.match /^w[i]?[s]?[d]?[o]?[m]?$/
    return 'Wisdom'
  elsif attr.to_s.downcase.match /^ch[a]?[r]?[i]?[s]?[m]?[a]?$/
    return 'Charisma'
  else
    puts "#{attr} is an invalid attribute value."
    exit 1
  end
end

# remove unnecessary to_s.downcase.match - flog: 9.7
def expand_attribute_arg3 attr
  if attr =3D~ /^s[t]?[r]?[e]?[n]?[g]?[t]?[h]?$/i
    return 'Strength'
  elsif attr =3D~ /^d[e]?[x]?[t]?[e]?[r]?[i]?[t]?[y]?$/i
    return 'Dexterity'
  elsif attr =3D~ /^co[n]?[s]?[t]?[i]?[t]?[u]?[t]?[i]?[o]?[n]?$/i
    return 'Constitution'
  elsif attr =3D~ /^i[n]?[t]?[e]?[l]?[l]?[i]?[g]?[e]?[n]?[c]?[e]?$/i
    return 'Intelligence'
  elsif attr =3D~ /^w[i]?[s]?[d]?[o]?[m]?$/i
    return 'Wisdom'
  elsif attr =3D~ /^ch[a]?[r]?[i]?[s]?[m]?[a]?$/i
    return 'Charisma'
  else
    puts "#{attr} is an invalid attribute value."
    exit 1
  end
end

# remove unnecessary regexp [c][a][s][e][s] - flog: 9.7
def expand_attribute_arg4 attr
  if attr =3D~ /^st?r?e?n?g?t?h?$/i
    return 'Strength'
  elsif attr =3D~ /^de?x?t?e?r?i?t?y?$/i
    return 'Dexterity'
  elsif attr =3D~ /^con?s?t?i?t?u?t?i?o?n?$/i
    return 'Constitution'
  elsif attr =3D~ /^in?t?e?l?l?i?g?e?n?c?e?$/i
    return 'Intelligence'
  elsif attr =3D~ /^wi?s?d?o?m?$/i
    return 'Wisdom'
  elsif attr =3D~ /^cha?r?i?s?m?a?$/i
    return 'Charisma'
  else
    puts "#{attr} is an invalid attribute value."
    exit 1
  end
end

# switch to case - flog: 9.6
def expand_attribute_arg5 attr
  case attr
  when /^st?r?e?n?g?t?h?$/i
    return 'Strength'
  when /^de?x?t?e?r?i?t?y?$/i
    return 'Dexterity'
  when /^con?s?t?i?t?u?t?i?o?n?$/i
    return 'Constitution'
  when /^in?t?e?l?l?i?g?e?n?c?e?$/i
    return 'Intelligence'
  when /^wi?s?d?o?m?$/i
    return 'Wisdom'
  when /^cha?r?i?s?m?a?$/i
    return 'Charisma'
  else
    puts "#{attr} is an invalid attribute value."
    exit 1
  end
end

# now that it is a lot less complex, you can see a lot more clearly
# that the regexps involved match a lot more than intended. eg: stgth
# either, you need s(?:t(?:r(?:e(?:n(?:g(?:t(?:h)?)?)?)?)?)?)? (ugh)
# or you need an entirely different approach: - flog: 13.6
def expand_attribute_arg6 attr
  {
    "strength"     =3D> 1,
    "dexterity"    =3D> 1,
    "constitution" =3D> 2,
    "intelligence" =3D> 1,
    "wisdom"       =3D> 1,
    "charisma"     =3D> 2,
  }.each do |str, len|
    return str.capitalize if attr.size >=3D len and =
str.index(attr.downcase) =3D=3D 0
  end
end

# or:

require "abbrev"

attribs =3D %w(strength dexterity constitution intelligence wisdom =
charisma)
ATTRIBS =3D Abbrev::abbrev attribs

# use abbrev - flog: 2.6
def expand_attribute_arg7 attr
  ATTRIBS[attr.downcase]
end

P.S. _NEVER_ exit from a library method. Raise and exit above. =
Rescuable, testable, maintainable.