53

例如:

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

如何将字符串拆分为:["Angry Birds", "2.4.1"]

4

10 回答 10

114

字符串#rpartition,例如

irb(main):068:0> str = "Angry Birds 2.4.1"
=> "Angry Birds 2.4.1"
irb(main):069:0> str.rpartition(' ')
=> ["Angry Birds", " ", "2.4.1"]

由于返回值是一个数组,因此使用.first.last可以将结果视为一分为二,例如

irb(main):073:0> str.rpartition(' ').first
=> "Angry Birds"
irb(main):074:0> str.rpartition(' ').last
=> "2.4.1"
于 2013-11-29T08:50:19.580 回答
11

我有一个这样的解决方案:

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"]
于 2012-08-30T08:20:57.657 回答
10

像这样的东西可能吗?拆分,其中一个空格后跟除空格之外的任何内容,直到字符串的末尾。

"Angry Birds 2.4.1".split(/ (?=\S+$)/)
#=> ["Angry Birds", "2.4.1"]
于 2012-08-30T08:15:07.923 回答
5

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! :-)

于 2015-04-27T17:36:58.120 回答
2

"Angry Birds 2.4.1".split(/ (?=\d+)/)

于 2012-08-30T08:04:01.167 回答
2

rpartition 解决方案是一个非常性感的单线(我投了赞成票),但是如果您想要一个更灵活地解决更复杂的分区问题的单线,这里有另一种技术:

["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.

于 2014-04-21T18:32:07.513 回答
1

这可能太棘手了(并且可能不是特别有效),但是您可以这样做:

"Angry Birds 2.4.1".reverse.split(" ", 2).map(&:reverse).reverse
于 2012-08-30T09:54:37.243 回答
1

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"]
于 2020-09-18T16:38:17.807 回答
1

reverse, split, then reverse every element and elements in array

"Angry Birds 2.4.1".reverse.split(' ', 2).map(&:reverse).reverse
于 2020-10-10T06:05:39.440 回答
0
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"]
于 2012-08-30T08:26:40.623 回答