Рубин: Разделить строку на символ, считая с правой стороны - PullRequest
25 голосов
/ 04 декабря 2009

Короткая версия - Как мне сделать Python rsplit () в ruby?

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

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

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

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

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

Ответы [ 6 ]

43 голосов
/ 04 декабря 2009

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

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

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

5 голосов
/ 04 декабря 2009

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

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

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

"whattodonow".split(/\.([^.]*)$/)
=> ["whattodonow"]
"what.to.do...now".split(/\.([^.]*)$/)
=> ["what.to.do..", "now"]
2 голосов
/ 04 декабря 2009

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

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

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

s = "what.to.do"

s.match(/(.*)\.(.*)/)[1..2]
=> ["what.to", "do"]
0 голосов
/ 24 мая 2019

Вы также можете добавить 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"]

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

0 голосов
/ 04 декабря 2009

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

"what.to.do".reverse.split('.', 2).map(&:reverse).reverse
=> ["what.to", "do"]
0 голосов
/ 04 декабря 2009

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

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

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

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