При поиске в огромных потоках данных использование reverse
определенно * приведет к проблемам с производительностью.Я использую string.rpartition
*:
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
p array_of_pieces.join
# "hello!hello?hello"
Тот же код должен работать со строкой без вхождений sub_or_pattern
:
string = "hello_hello_hello"
# ...
# "hello_hello_hello"
*rpartition
использует rb_str_subseq()
внутренне,Я не проверял, возвращает ли эта функция копию строки, но я думаю, что она сохраняет часть памяти, используемую этой частью строки.reverse
использует rb_enc_cr_str_copy_for_substr()
, что предполагает, что копии выполняются постоянно - хотя, возможно, в будущем может быть реализован более умный класс String
(с флагом reversed
, установленным в значение true, и имеющим все его функцииработая в обратном направлении, когда это установлено), на данный момент, это неэффективно.
Более того, шаблоны Regex
нельзя просто поменять местами.Вопрос требует только замены последнего вхождения подстроки, так что все в порядке, но читатели, нуждающиеся в чем-то более надежном, не получат пользу от ответа с наибольшим количеством голосов (на момент написания статьи)