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
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!