When searching in huge streams of data, using
reverse will definitively* lead to performance issues. I use
sub_or_pattern = "!"
replacement = "?"
string = "hello!hello!hello"
array_of_pieces = string.rpartition sub_or_pattern
( array_of_pieces[(array_of_pieces.find_index sub_or_pattern)] = replacement ) rescue nil
The same code must work with a string with no occurrences of
string = "hello_hello_hello"
rb_str_subseq() internally. I didn't check if that function returns a copy of the string, but I think it preserves the chunk of memory used by that part of the string.
rb_enc_cr_str_copy_for_substr(), which suggests that copies are done all the time -- although maybe in the future a smarter
String class may be implemented (having a flag
reversed set to true, and having all of its functions operating backwards when that is set), as of now, it is inefficient.
Regex patterns can't be simply reverted. The question only asks for replacing the last occurrence of a sub-string, so, that's OK, but readers in the need of something more robust won't benefit from the most voted answer (as of this writing)