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

前端 未结 10 1144
南笙
南笙 2021-02-03 20:08

I want to replace the last occurrence of a substring in Ruby. What\'s the easiest way? For example, in abc123abc123, I want to replace the last abc

相关标签:
10条回答
  • 2021-02-03 21:05

    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

    0 讨论(0)
  • 2021-02-03 21:11

    I've used this handy helper method quite a bit:

    def gsub_last(str, source, target)
      return str unless str.include?(source)
      top, middle, bottom = str.rpartition(source)
      "#{top}#{target}#{bottom}"
    end
    

    If you want to make it more Rails-y, extend it on the String class itself:

    class String
      def gsub_last(source, target)
        return self unless self.include?(source)
        top, middle, bottom = self.rpartition(source)
        "#{top}#{target}#{bottom}"
      end
    end
    

    Then you can just call it directly on any String instance, eg "fooBAR123BAR".gsub_last("BAR", "FOO") == "fooBAR123FOO"

    0 讨论(0)
  • 2021-02-03 21:12

    You can achieve this with String#sub and greedy regexp .* like this:

    'abc123abc123'.sub(/(.*)abc/, '\1ABC')
    
    0 讨论(0)
  • 2021-02-03 21:12
    string = "abc123abc123"
    pattern = /abc/
    replacement = "ABC"
    
    matches = string.scan(pattern).length
    index = 0
    string.gsub(pattern) do |match|
      index += 1
      index == matches ? replacement : match
    end
    #=> abc123ABC123
    
    0 讨论(0)
提交回复
热议问题