Ruby: Разделить строку на символ, считая с правой стороны
Краткая версия. Как сделать python rsplit() в ruby?
Более длинная версия. Если я хочу разбить строку на две части (имя, суффикс) на первом ".". характер, это делает работу красиво:
name, suffix = name.split('.', 2)
Но если я хочу разбить на последнем (самом крайнем) '.' характер, я не смог придумать ничего более элегантного, чем это:
idx = name.rindex('.')
name, suffix = name[0..idx-1], name[idx+1..-1] if idx
Обратите внимание, что исходная строка имени может вообще не иметь точки, и в этом случае имя должно быть нетронутым, а суффикс должен быть равен нулю; он может также иметь более одной точки, и в этом случае только бит после окончательного должен быть суффиксом.
Ответы
Ответ 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"]
Но я не могу понять, как это разделить.