Skip to content

Instantly share code, notes, and snippets.

@addywaddy
Created May 22, 2012 07:55
Show Gist options
  • Save addywaddy/2767432 to your computer and use it in GitHub Desktop.
Save addywaddy/2767432 to your computer and use it in GitHub Desktop.
RegexpHash: Hash subclass for building nested regular expressions
class RegexpHash < Hash
def add_word(word, hsh = nil)
hsh ||= self
return unless (word && word.length > 0)
key = word.slice(0..0)
hsh[key] ||= {}
add_word(word.slice(1..-1), hsh[key])
end
def flatten!(hsh = nil)
hsh ||= self
hsh.keys.each do |key|
if hsh[key] && (hsh[key].keys.length == 1)
child_key = hsh[key].keys[0]
child_value = hsh[key][child_key]
hsh[key + child_key] = child_value
hsh.delete(key)
flatten!(hsh) if child_value
else
flatten!(hsh[key]) if hsh[key]
end
end
end
def to_regexp
flatten!
pattern = self.inspect.
gsub("{", "(").
gsub("}", ")").
gsub(',', '|').
gsub('()', '').
gsub(/(\"|=\>|\s)/,'')
Regexp.new(pattern)
end
end
store = RegexpHash.new
["doggy", "dolly", "dilbert", "dogbert"].each do |word|
store.add_word(word)
end
puts store.to_regexp
# => (?-mix:(d(o(lly|g(bert|gy))|ilbert)))
p "doggy dolly bert xxxdogbertxxx".scan(store.to_regexp)
# => [["doggy", "oggy", "ggy", "gy"], ["dolly", "olly", "lly", nil], ["dogbert", "ogbert", "gbert", "bert"]]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment