Подтвердить что ты не робот

Ruby: Разделить строку на символ, считая с правой стороны

Краткая версия. Как сделать python rsplit() в ruby?

Более длинная версия. Если я хочу разбить строку на две части (имя, суффикс) на первом ".". характер, это делает работу красиво:

name, suffix = name.split('.', 2)

Но если я хочу разбить на последнем (самом крайнем) '.' характер, я не смог придумать ничего более элегантного, чем это:

idx = name.rindex('.')
name, suffix = name[0..idx-1], name[idx+1..-1] if idx

Обратите внимание, что исходная строка имени может вообще не иметь точки, и в этом случае имя должно быть нетронутым, а суффикс должен быть равен нулю; он может также иметь более одной точки, и в этом случае только бит после окончательного должен быть суффиксом.

4b9b3361

Ответ 1

String#rpartition делает именно это:

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

Он был введен в Ruby 1.8.7, поэтому, если вы используете более раннюю версию, вы можете использовать require 'backports/1.8.7/string/rpartition' для этого.

Ответ 2

Надавите на колпачок мышления на некоторое время и придумайте это регулярное выражение:

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

Или в человеческих терминах "разбивается на точку, а не на другую точку, в конце строки". Хорошо работает и с бесчисленными строками и последовательностями точек:

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

Ответ 3

Вот что я на самом деле делал:

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

или, возможно, более условно,

s = "what.to.do"

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

Ответ 4

если это = "what.to.do", вы можете сделать это:

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

и вы вернетесь

["", "what.to", "do"]

Ответ 5

Если вам нужна буквальная версия rsplit, вы можете сделать это (это отчасти шутка, но на самом деле хорошо работает):

"what.to.do".reverse.split('.', 2).map(&:reverse).reverse
=> ["what.to", "do"]

Ответ 6

Вы также можете добавить rsplit к классу String, добавив его вверху вашего файла.

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

Это не совсем похоже на разделение. например

$ 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"]

против

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

Но я не могу понять, как это разделить.