How to Replace the Last Occurrence of a Substring in Ruby

How to replace the last occurrence of a substring in ruby?

Since Ruby 2.0 we can use \K which removes any text matched before it from the returned match. Combine with a greedy operator and you get this:

'abc123abc123'.sub(/.*\Kabc/, 'ABC')
#=> "abc123ABC123"

This is about 1.4 times faster than using capturing groups as Hirurg103 suggested, but that speed comes at the cost of lowering readability by using a lesser-known pattern.

more info on \K: https://www.regular-expressions.info/keep.html

Replace final comma in a string with ' & ' - Ruby

The sub method replaces only the first occurrence, so you can reverse, sub and reverse again.

"Ruby on Rails, Ruby, String, Replace".reverse.sub(',', '& ').reverse

How to find last occurrence of a number in a string using Ruby?

There are answers how to do what you need

Also to find last occurence of number:

x = 'blah_blah.do.dah[4543]junk_junk'
x.rindex(/\d/)

Ruby Regex Replace Last Occurence of Grouping

If I correctly understood, you are interested in gsub with codeblock:

str.gsub(PATTERN) { |mtch|
puts mtch # the whole match
puts $~[3] # the third group
mtch.gsub($~[3], 'NEW') # the result
}

'abc'.gsub(/(b)(c)/) { |m| m.gsub($~[2], 'd') }
#⇒ "abd"

Probably you should handle the case when there are no 40-s occureneces at all, like:

gsub($~[1], "NEW$~[1]") if $~[3].nil?

To handle all the possible cases, one might declare the group for Foo:

#                           NOTE THE GROUP ⇓⇓⇓⇓⇓
▶ re = /(([1-3,5-9][0-9]|([4][0-9]))[a-z])*(Foo)/
#⇒ /(([1-3,5-9][0-9]|([4][0-9]))[a-z])*(Foo)/
▶ inp.gsub(re) do |mtch|
▷ $~[3].nil? ? mtch.gsub($~[4], "NEW#{$~[4]}") : mtch.gsub(/#{$~[3]}/, 'NEW')
▷ end
#⇒ "12a23b34cNEWd56eFoo\n12a45b34cNEWd89eFoo\nNEWaFoo\nNEWFoo\n12a23bNEWFoo"

Hope it helps.

Replace the last match in a string

If you just want to increment the integer at the very end of a string then try this:

s = '2.0.0.65'
s.sub(/\d+\Z/) {|x| x.to_i + 1} # => '2.0.0.66'


Related Topics



Leave a reply



Submit