web-dev-qa-db-ja.com

Ruby:右側から数えて文字列を分割します

短いバージョン-RubyでPython rsplit()を実行するにはどうすればよいですか?

長いバージョン-文字列を最初の「。」で2つの部分(名前、サフィックス)に分割したい場合。文字、これはうまく仕事をします:

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

しかし、最後(右端)で分割したい場合 '。'キャラクター、私はこれよりエレガントなものを思い付くことができませんでした:

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

元の名前文字列にはドットがまったく含まれていない可能性があることに注意してください。その場合、名前は変更せず、サフィックスはnilにする必要があります。また、複数のドットが含まれる場合もあります。その場合、最後のビットの後のビットのみがサフィックスになります。

26
jpatokal

String#rpartition それを行います:

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

Ruby 1.8.7で導入されたため、以前のバージョンを実行している場合は、 require 'backports/1.8.7/string/rpartition' それが機能するために。

44

しばらくの間思考の上限を設定し、この正規表現を思いついた:

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

または、人間の用語では、「文字列の終わりで、別のドットが続かないドットで分割」します。ドットのない文字列やドットのシーケンスでもうまく機能します。

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

これが私が実際に行うことです:

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

またはおそらくもっと慣習的に、

s = "what.to.do"

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

ファイルの先頭にこれを追加することで、Stringクラスにrsplitを追加することもできます。

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

vs.

[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
Marlen T. B.

this = "what.to.do"の場合、次のことができます。

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

そして、あなたは戻ってきます

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

rsplitの文字通りのバージョンが必要な場合は、これを行うことができます(これは部分的に冗談ですが、実際にはうまく機能します)。

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