Ruby regex group replacement
I am trying to do regex and replace on the same line in Ruby. I have several libraries that manipulate strings in Ruby and add special formatting characters to them. Formatting can be applied in any order. However, if I would like to change the formatting of the strings, I want to keep some of the original formatting. I am using regex for this. I am using the regex correctly that I need:
mystring.gsub(/[(\e\[([1-9]|[1,2,4,5,6,7,8]{2}m))|(\e\[[3,9][0-8]m)]*Text/, 'New Text')
However, what I really want is a match with the first grouping found in:
(\e\[([1-9]|[1,2,4,5,6,7,8]{2}m))
which is appended to New Text
and replaced instead of New Text
. I am trying to reference a match in the form
mystring.gsub(/[(\e\[([1-9]|[1,2,4,5,6,7,8]{2}m))|(\e\[[3,9][0-8]m)]*Text/, '\1' + 'New Text')
but I understand that \1
only works when using \d
or \k
. Is there a way to reference this particular capture group in my replacement string? Also, since I am using asterik for []
, I know that this grouping can happen more than once. So I would like to get the last match.
My expected I / O with sample:
Input: "\e[1mHello there\e[34m\e[40mText\e[0m\e[0m\e[22m"
Output: "\e[1mHello there\e[40mNew Text\e[0m\e[0m\e[22m"
Input: "\e[1mHello there\e[44m\e[34m\e[40mText\e[0m\e[0m\e[22m"
Output: "\e[1mHello there\e[40mNew Text\e[0m\e[0m\e[22m"
So, the last grouping has been found and added.
source to share
You can use the following regex with backreference \\1
in replacement:
reg = /(\\e\[(?:[0-9]{1,2}|[3,9][0-8])m)+Text/
mystring = "\\e[1mHello there\\e[34m\\e[40mText\\e[0m\\e[0m\\e[22m"
puts mystring.gsub(reg, '\\1New Text')
mystring = "\\e[1mHello there\\e[44m\\e[34m\\e[40mText\\e[0m\\e[0m\\e[22m"
puts mystring.gsub(reg, '\\1New Text')
Conclusion demos ideone :
\e[1mHello there\e[40mNew Text\e[0m\e[0m\e[22m \e[1mHello there\e[40mNew Text\e[0m\e[0m\e[22m
Remember that your input has a backslash \
that needs escaping in a regular string literal. To match it within the regex, we use a double slash as we are looking for a literal backslash.
source to share