Ruby: Split string at character, counting from the right side

后端 未结 6 1422
小蘑菇
小蘑菇 2020-12-10 00:59

Short version -- How do I do Python rsplit() in ruby?

Longer version -- If I want to split a string into two parts (name, suffix) at the first \'.\' character, this

相关标签:
6条回答
  • 2020-12-10 01:22

    You can also add rsplit to the String class by adding this at the top of your file.

    class String
      def rsplit(pattern=nil, limit=nil)
        array = self.split(pattern)
        left = array[0...-limit].join(pattern)
        right_spits = array[-limit..]
        return [left] + right_spits
      end
    end
    

    It doesn't quite work like split. e.g.

    $ pry
    [1] pry(main)> s = "test.test.test"
    => "test.test.test"
    [2] pry(main)> s.split('.', 1)
    => ["test.test.test"]
    [3] pry(main)> s.split('.', 2)
    => ["test", "test.test"]
    [4] pry(main)> s.split('.', 3)
    => ["test", "test", "test"]
    

    vs.

    [6] pry(main)> s
    => "test.test.test"
    [7] pry(main)> s.rsplit('.', 1)
    => ["test.test", "test"]
    [8] pry(main)> s.rsplit('.', 2)
    => ["test", "test", "test"]
    

    But I can't quite work out how to short split it.

    0 讨论(0)
  • 2020-12-10 01:24

    If you want the literal version of rsplit, you can do this (this is partly a joke, but actually works well):

    "what.to.do".reverse.split('.', 2).map(&:reverse).reverse
    => ["what.to", "do"]
    
    0 讨论(0)
  • 2020-12-10 01:26

    if this="what.to.do" you can do this:

    this.split(%r{(.+)\.})
    

    and you'll get back

    ["", "what.to", "do"]
    
    0 讨论(0)
  • 2020-12-10 01:37

    Put on the thinking cap for a while and came up with this regexp:

    "what.to.do.now".split(/\.([^.]*)$/)
    => ["what.to.do", "now"]
    

    Or in human terms "split at dot, not followed by another dot, at end of string". Works nicely also with dotless strings and sequences of dots:

    "whattodonow".split(/\.([^.]*)$/)
    => ["whattodonow"]
    "what.to.do...now".split(/\.([^.]*)$/)
    => ["what.to.do..", "now"]
    
    0 讨论(0)
  • 2020-12-10 01:42

    String#rpartition does just that:

    name, match, suffix = name.rpartition('.')
    

    It was introduced in Ruby 1.8.7, so if running an earlier version you can use require 'backports/1.8.7/string/rpartition' for that to work.

    0 讨论(0)
  • 2020-12-10 01:42

    Here's what I'd actually do:

    /(.*)\.(.*)/.match("what.to.do")[1..2]
    => ["what.to", "do"]
    

    or perhaps more conventionally,

    s = "what.to.do"
    
    s.match(/(.*)\.(.*)/)[1..2]
    => ["what.to", "do"]
    
    0 讨论(0)
提交回复
热议问题