How to split a string into only two parts, by the last occurrence of the split char?

前端 未结 10 1395
猫巷女王i
猫巷女王i 2020-12-29 01:22

For example:

\"Angry Birds 2.4.1\".split(\" \", 2)
 => [\"Angry\", \"Birds 2.4.1\"] 

How can I split the string into: [\"Angry Bir

相关标签:
10条回答
  • 2020-12-29 01:39

    Create a String#split_on_last method.

    Heavily inspired by halfelf's answer but permits more than just a single character, doesn't have a default param value and refactored for clarity.

    Definition

    Class String
      def split_on_last( text )
        position_of_last_occurrence = self.rindex( text )
    
        return self if position_of_last_occurrence.nil?
    
        first_part = self[ 0...position_of_last_occurrence ]
        last_part  = self[ position_of_last_occurrence + text.length..-1 ]
    
        [ first_part, last_part ]
      end
    end
    

    Usage

    "Angry Birds 2.4.1".split_on_last( " " )
    #=> ["Angry Birds", "2.4.1"]
    
    "start middle end end suffix".split_on_last( "end" )
    => ["start middle end ", " suffix"]
    
    0 讨论(0)
  • 2020-12-29 01:41

    I don't seem able to get the example code in my comment properly formatted, so I'm submitting it as a separate answer, even though Vadym Tyemirov deserves all the credit for the String#rpartition solution he provided above.

    I just wanted to add that String#rpartition plays very nicely with Ruby's "don't care" variable, as typically you're indeed only interested in the first and last element of the result array, but not the middle element (the separator):

    [1] pry(main)> name, _, version = "Angry Birds 2.4.1".rpartition(' ')
    => ["Angry Birds", " ", "2.4.1"]
    [2] pry(main)> name
    => "Angry Birds"
    [3] pry(main)> version
    => "2.4.1"
    

    So no need for Array#first or Array#last... less is more! :-)

    0 讨论(0)
  • 2020-12-29 01:43

    The rpartition solution makes a great sexy one-liner (I voted for it), but here's another technique if you want a one liner that's more flexible for solving more complex partitioning problems:

    ["Angry Birds 2.4.1".split(' ')[0..-2].join(' '), "Angry Birds 2.4.1".split(' ')[-1..-1].join(' ')]
    

    By more flexible, I mean if there were more items being partitioned, you could just adjust the range of the sequence.

    0 讨论(0)
  • 2020-12-29 01:44

    I hava a solution like this:

    class String
      def split_by_last(char=" ")
        pos = self.rindex(char)
        pos != nil ? [self[0...pos], self[pos+1..-1]] : [self]
      end
    end
    
    "Angry Birds 2.4.1".split_by_last  #=> ["Angry Birds", "2.4.1"]
    "test".split_by_last               #=> ["test"]
    
    0 讨论(0)
  • 2020-12-29 01:47

    This is probably way too tricky (and probably not particularly efficient), but you can do this:

    "Angry Birds 2.4.1".reverse.split(" ", 2).map(&:reverse).reverse
    
    0 讨论(0)
  • 2020-12-29 01:47
    class String
      def divide_into_two_from_end(separator = ' ')
        self.split(separator)[-1].split().unshift(self.split(separator)[0..-2].join(separator))
      end
    end
    
    "Angry Birds 2.4.1".divide_into_two_from_end(' ') #=> ["Angry Birds", "2.4.1"]
    
    0 讨论(0)
提交回复
热议问题