I had fun with this quiz.=0A=0A/Ruby (should be|better be|is) (very )* fun[=
..!] (You see\?)?/.generate=0A=0A=3D>["Ruby should be  fun. ", "Ruby should =
be  fun. You see?", "Ruby should be  fun! ", "Ruby should be  fun! You see?=
", "Ruby should be very  fun. ", "Ruby should be very  fun. You see?", "Rub=
y should be very  fun! ", "Ruby should be very  fun! You see?", "Ruby shoul=
d be very very  fun. ", "Ruby should be very very  fun. You see?", "Ruby sh=
ould be very very  fun! ", "Ruby should be very very  fun! You see?", "Ruby=
 should be very very very  fun. ", "Ruby should be very very very  fun. You=
 see?", "Ruby should be very very very  fun! ", "Ruby should be very very v=
ery  fun! You see?", "Ruby should be very very very very  fun. ", "Ruby sho=
uld be very very very very  fun. You see?", "Ruby should be very very very =
very  fun! ", "Ruby should be very very very very  fun! You see?", "Ruby sh=
ould be very very very very very  fun. ", "Ruby should be very very very ve=
ry very  fun. You see?", "Ruby should be very very very very very  fun! ", =
"Ruby should be very very
 very very very  fun! You see?", "Ruby better be  fun. ", "Ruby better be  =
fun. You see?", "Ruby better be  fun! ", "Ruby better be  fun! You see?", "=
Ruby better be very  fun. ", "Ruby better be very  fun. You see?", "Ruby be=
tter be very  fun! ", "Ruby better be very  fun! You see?", "Ruby better be=
 very very  fun. ", "Ruby better be very very  fun. You see?", "Ruby better=
 be very very  fun! ", "Ruby better be very very  fun! You see?", "Ruby bet=
ter be very very very  fun. ", "Ruby better be very very very  fun. You see=
?", "Ruby better be very very very  fun! ", "Ruby better be very very very =
 fun! You see?", "Ruby better be very very very very  fun. ", "Ruby better =
be very very very very  fun. You see?", "Ruby better be very very very very=
  fun! ", "Ruby better be very very very very  fun! You see?", "Ruby better=
 be very very very very very  fun. ", "Ruby better be very very very very v=
ery  fun. You see?", "Ruby better be very very very very very  fun!
 ", "Ruby better be very very very very very  fun! You see?", "Ruby is  fun=
.. ", "Ruby is  fun. You see?", "Ruby is  fun! ", "Ruby is  fun! You see?", =
"Ruby is very  fun. ", "Ruby is very  fun. You see?", "Ruby is very  fun! "=
, "Ruby is very  fun! You see?", "Ruby is very very  fun. ", "Ruby is very =
very  fun. You see?", "Ruby is very very  fun! ", "Ruby is very very  fun! =
You see?", "Ruby is very very very  fun. ", "Ruby is very very very  fun. Y=
ou see?", "Ruby is very very very  fun! ", "Ruby is very very very  fun! Yo=
u see?", "Ruby is very very very very  fun. ", "Ruby is very very very very=
  fun. You see?", "Ruby is very very very very  fun! ", "Ruby is very very =
very very  fun! You see?", "Ruby is very very very very very  fun. ", "Ruby=
 is very very very very very  fun. You see?", "Ruby is very very very very =
very  fun! ", "Ruby is very very very very very  fun! You see?"]=0A=0AThank=
 you to Evan for making the comment about nesting. My solution broke on nes=
ting. Luckily, that was easy to fix.=0A=0A/(a+(bc)?){1,2}/.generate=0A=3D>[=
"a", "abc", "aa", "aabc", "aaa", "aaabc", "aaaa", "aaaabc", "aaaaa", "aaaaa=
bc", "aa", "aabc", "aaa", "aaabc", "aaaa", "aaaabc", "aaaaa", "aaaaabc", "a=
aaaaa", "aaaaaabc", "abca", "abcabc", "abcaa", "abcaabc", "abcaaa", "abcaaa=
bc", "abcaaaa", "abcaaaabc", "abcaaaaa", "abcaaaaabc", "aaa", "aaabc", "aaa=
a", "aaaabc", "aaaaa", "aaaaabc", "aaaaaa", "aaaaaabc", "aaaaaaa", "aaaaaaa=
bc", "aabca", "aabcabc", "aabcaa", "aabcaabc", "aabcaaa", "aabcaaabc", "aab=
caaaa", "aabcaaaabc", "aabcaaaaa", "aabcaaaaabc", "aaaa", "aaaabc", "aaaaa"=
, "aaaaabc", "aaaaaa", "aaaaaabc", "aaaaaaa", "aaaaaaabc", "aaaaaaaa", "aaa=
aaaaabc", "aaabca", "aaabcabc", "aaabcaa", "aaabcaabc", "aaabcaaa", "aaabca=
aabc", "aaabcaaaa", "aaabcaaaabc", "aaabcaaaaa", "aaabcaaaaabc", "aaaaa", "=
aaaaabc", "aaaaaa", "aaaaaabc", "aaaaaaa", "aaaaaaabc", "aaaaaaaa", "aaaaaa=
aabc", "aaaaaaaaa", "aaaaaaaaabc", "aaaabca", "aaaabcabc", "aaaabcaa", "aaa=
abcaabc", "aaaabcaaa", "aaaabcaaabc", "aaaabcaaaa",
 "aaaabcaaaabc", "aaaabcaaaaa", "aaaabcaaaaabc", "aaaaaa", "aaaaaabc", "aaa=
aaaa", "aaaaaaabc", "aaaaaaaa", "aaaaaaaabc", "aaaaaaaaa", "aaaaaaaaabc", "=
aaaaaaaaaa", "aaaaaaaaaabc", "aaaaabca", "aaaaabcabc", "aaaaabcaa", "aaaaab=
caabc", "aaaaabcaaa", "aaaaabcaaabc", "aaaaabcaaaa", "aaaaabcaaaabc", "aaaa=
abcaaaaa", "aaaaabcaaaaabc"]=0A=0A=0A=0AMy solution uses a macro-character =
system inspired by the Lisp parser. Every time it encounters a special char=
acter, it calls a function associated with that character, passing in both =
the tree it's encountered so far, and the reader. This tree isn't actually =
a physical tree, however. Instead, it consists of functions that generate a=
ll possible combinations of a segment of the regex. Each function is currie=
d with the relevant arguments so as to require no new arguments. For exampl=
e, the regex-segment "a{1,2}" becomes quantified_range curried with  the ra=
nge 1..2 and the method quote, which is in turn curried with "a". The array=
 that is passed in to the macro-character functions consists of all of thos=
e trees of curried functions that have been seen so far; these will eventua=
lly be curried into the capturing_group method by the parse_regex method. A=
 capturing group, in this case, is not only anything between unescaped pare=
ntheses but also the top level of
 the regex itself.=0A=0AMy solutions supports most of regex syntax. Non-cap=
turing groups should be an unmissed exception, as should be more exotic quo=
ting. Unfortunately, I could not think of a way to add in backreferencing c=
apturing groups. My first thoughts involved having a global array referenci=
ng all capturing groups and then having backreferencing refer to that, but =
I couldn't think of a way so that each backreference would know which chara=
cters were matched by its capturing group in that particular match.  Having=
 the tree be evalutated sequentially  rather than layer-by-layer as it is n=
ow (i.e.: rather than having the possibilities for each segment evaluated a=
nd then applying higher functions on those possibilities, do something more=
 of an inorder traversal, so that all possibilities if a capturing group ma=
tches some characters are generated before the possibilities of the next po=
ssibility for the capturing group are encountered) was briefly thought of, =
but that would
 make this solution several times more complex (i.e.: needing actual tree n=
odes rather than curried methods).=0A=0AA few notes: Since + and * can matc=
h infinite amounts of characters, I just have them match upto the value of =
INF_QUANTIFIER_LEN, which is set to 5. Additionally, I anything along the l=
ines of /|a/ will not work (though /a|/ does work); however, should I bothe=
r, I can make a work-around with ease.=0A=0AAnyway, here's the code:=0A=0AI=
NF_QUANTIFIER_LEN =3D 5=0A=0Amodule Invokable=0A  def curry(*largs)=0A    p=
roc {|*args| self.call(*(largs+args))}=0A  end=0Aend=0Aclass Method=0A  inc=
lude Invokable=0Aend=0A=0A$escape_seqs =3D {=0A  ?a =3D> ?\a,=0A  ?b =3D> ?=
\b,=0A  ?f =3D> ?\f,=0A  ?n =3D> ?\n,=0A  ?r =3D> ?\r,=0A  ?t =3D> ?\t,=0A =
 ?v =3D> ?\v=0A}=0A=0A$predefined_classes =3D {=0A  ?d =3D> (?0..?9).to_a,=
=0A  ?D =3D> (0..255).to_a - (?0..?9).to_a,=0A  ?s =3D> [" "[0], ?\t,?\n,?\=
v,?\r],=0A  ?S =3D> (0..255).to_a - [" "[0], ?\t,?\n,?\v,?\r],=0A  ?w =3D> =
(?a..?z).to_a + (?A..?Z).to_a + (?0..?9).to_a + [?_],=0A  ?W =3D> (0..255).=
to_a - =0A       ((?a..?z).to_a + (?A..?Z).to_a + (?0..?9).to_a + [?_])=0A}=
=0A=0A###Given a StringIO removes the next character if it's a ?=0Adef remo=
ve_reluctant(strio)=0A  return if strio.eof?=0A  if (ch=3Dstrio.getc) =3D=
=3D ??=0A    #Do nothing=0A  else=0A    strio.ungetc(ch)=0A  end=0Aend=0A=
=0A###Given a StringIO, returns the everything until an unnested closed par=
enthesis is read=0Adef get_outer_layer(strio)=0A  str =3D ""=0A  nest =3D 0=
=0A  until (ch=3Dstrio.read(1)) =3D=3D ')' and nest =3D=3D 0=0A    str << c=
h=0A    str << strio.read(1) if ch =3D=3D "\\"=0A    nest +=3D 1 if ch =3D=
=3D '('=0A    nest -=3D 1 if ch =3D=3D ')'=0A  end=0A  str=0Aend=0A=0A###Re=
turns an array whose elements are subarrays containing all distinct=0A###co=
mbinations of one element from each argument=0Adef all_combinations(first, =
*rest)=0A  return first if rest =3D=3D []=0A  rest =3D all_combinations(*re=
st)=0A  combs =3D []=0A  first.each do |v1|=0A    rest.each do |v2|=0A     =
 combs << v1 + v2=0A    end=0A  end=0A  combs=0Aend=0A=0A###The following m=
ethods return an array of all valid matches to the entity.=0A###=0A###Note:=
 The functions corresponding to regex operators that operate on =0A###valid=
 subregexes accept curried functions that return the values to operate on,=
=0A###not the values themselves. (That's why the quote function exists.)=0A=
=0Adef char_class(ascii_vals)=0A  ascii_vals.map{|i|i.chr}=0Aend=0A=0Adef o=
r(left, right)=0A  left.call+right.call=0Aend=0A=0Adef quantified_range(ran=
ge, vals)=0A  vals =3D [vals.call] * range.end=0A  range.to_a.map{|n|n =3D=
=3D 0 ? "" : all_combinations(*vals[0..(n-1)])}.flatten=0Aend=0A=0Adef capt=
uring_group(vals)=0A  all_combinations(*vals.map{|f|f.call})=0Aend=0A=0Adef=
 quote(val)=0A  [val]=0Aend=0A=0A###Following is a hash that maps character=
s to procedures accepting the=0A###previously-encountered entities and the =
StringIO of the regex-source reader.=0A###These procedures add to prev curr=
ied functions that a form a tree of functions=0A###that return all possible=
 values=0A$macro_chars =3D {=0A  ?\\ =3D> proc do |prev, strio|=0A         =
     ch =3D strio.getc=0A              prev << if $predefined_classes.has_k=
ey? ch=0A                            method(:char_class).curry($predefined_=
classes[ch])=0A                          elsif $escape_seqs.has_key? ch=0A =
                           method(:quote).curry($escape_seqs[ch])=0A       =
                   else=0A                            method(:quote).curry(=
ch.chr)=0A                          end=0A            end,=0A  ?. =3D> proc=
 do |prev, strio|=0A            prev << method(:char_class).curry((0..255).=
to_a)=0A          end,=0A  ?[ =3D> proc do |prev,strio|=0A            ascii=
_vals =3D []=0A            =0A            char_str =3D strio.gets("]")[0...=
-1]=0A            =0A            neg =3D if char_str[0] =3D=3D ?^=0A       =
               char_str =3D char_str[1..-1]=0A                      true=0A=
                    else=0A                      false=0A                  =
  end=0A              =0A            ##The next three lines handle escape c=
haracters. \- is a special case=0A            char_str.gsub!(/\\-/) {ascii_=
vals << ?-; ""}=0A            char_str.gsub!(/\\(.)/) {=0A              $es=
cape_seqs.has_key?($1[0]) ? $escape_seqs[$1[0]] : $1}=0A            char_st=
r.scan(/.-.|./) do |seg|=0A              if seg =3D~ /(.)-(.)/=0A          =
      ascii_vals +=3D (($1[0])..($2[0])).to_a=0A              else=0A      =
          ascii_vals << seg[0]=0A              end=0A            end=0A    =
        prev << method(:char_class).curry(=0A              neg ? (0..255).t=
o_a - ascii_vals : ascii_vals)=0A          end,=0A  ?( =3D> proc do |prev,s=
trio|=0A            prev << parse_regex(get_outer_layer(strio))=0A         =
  end,=0A  ?* =3D> proc do |prev, strio|=0A              remove_reluctant(s=
trio)=0A              prev[-1] =3D method(:quantified_range).=0A           =
       curry(0..INF_QUANTIFIER_LEN, prev[-1])=0A            end,=0A  ?+ =3D=
> proc do |prev, strio|=0A              remove_reluctant(strio)=0A         =
     prev[-1] =3D method(:quantified_range).=0A                  curry(1..I=
NF_QUANTIFIER_LEN, prev[-1])=0A           end,=0A    ?? =3D> proc do |prev,=
 strio|=0A              remove_reluctant(strio)=0A              prev[-1] =
=3D method(:quantified_range).=0A                  curry(0..1, prev[-1])=0A=
             end,=0A    ?{ =3D> proc do |prev, strio|=0A              remov=
e_reluctant(strio)=0A              contents =3D strio.gets("}")=0A         =
     prev[-1] =3D  if contents =3D~ /(\d),(\d)/=0A                         =
        method(:quantified_range).curry(($1.to_i)..($2.to_i), prev[-1])=0A =
                             elsif contents=3D~ /(\d),/=0A                 =
                method(:quantified_range).curry(=0A                        =
           ($1.to_i)..INF_QUANTIFIER_LEN, prev[-1])=0A                     =
          elsif contents =3D~ /(\d)/=0A                                 met=
hod(:quantified_range).curry(($1.to_i)..($1.to_i), prev[-1])=0A            =
                   end=0A              end,=0A    ?| =3D> proc do |prev, st=
rio|=0A              prev[0..-1] =3D method(:or).curry(=0A                 =
   method(:capturing_group).curry(prev[0..-1]),=0A                    parse=
_regex(strio.gets(nil)))=0A                  end=0A}=0A=0Adef parse_regex(s=
rc)=0A  return method(:quote).curry("") if src =3D=3D "" or src.nil?=0A  fu=
nc_arr =3D []=0A  strio =3D StringIO.new(src)=0A  until strio.eof?=0A    ch=
 =3D strio.getc=0A    if $macro_chars.has_key? ch=0A      $macro_chars[ch].=
call(func_arr, strio)=0A    else=0A      func_arr << method(:quote).curry(c=
h.chr)=0A    end=0A  end=0A  method(:capturing_group).curry(func_arr)=0Aend=
=0A=0Aclass Regexp=0A  def generate=0A    parse_regex(self.source).call=0A =
 end=0Aend=0A=0A=0A=0A      _______________________________________________=
_____________________________________=0AFussy? Opinionated? Impossible to p=
lease? Perfect.  Join Yahoo!'s user panel and lay it on us. http://surveyli=
nk.yahoo.com/gmrs/yahoo_panel_invite.asp?a=3D7 =0A