Hello!

I'm writing an ANSI color codes parser which gets a string with text  
and ANSI color codes and outputs an array with substrings and numbers  
of the color codes.
A color code is something like "\e[31m". Generally, I assume (am I  
wrong?) they match /\e\[(\d+)(;\d+)*m/.

Here is what I came up with:


module ANSIParser
   def self.ansi_to_array(str)
     str = str.to_s
     ret = []
     while ((m = /\e\[(\d+)(;\d+)*m/.match(str)))
       ret << m.pre_match if m.pre_match != ""
       ret += m[0].scan(/\d+/).map { |c| c.to_i }
       str = m.post_match
     end
     ret << str if str != ""
     return ret
   end
end

# TEST:
ansistr = "\e[31mred,\e[32;1m\e[32;1mbold green\e[33;32;31mred  
anyway, still bold\e[33;32;31m"

puts ansistr # you should see colors if your terminal supports ANSI  
escapes
puts ANSIParser::ansi_to_array(ansistr).inspect


It works, but it doesn't look much elegant. In fact, it looks much  
more like perl than ruby to me :P
That while over there is awful. Is there a way to make it more  
elegant? Is there some kind of iterator which does what my while  
does? If not, would you split it somehow?

I'm looking for suggestions :)
Thanks!