tags:

views:

1092

answers:

5

Short version -- How do I do Python rsplit() in ruby?

Longer version -- If I want to split a string into two parts (name, suffix) at the first '.' character, this does the job nicely:

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

But if I want to split at the last (rightmost) '.' character, I haven't been able to come up with anything more elegant than this:

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

Note that the original name string may not have a dot at all, in which case name should be untouched and suffix should be nil; it may also have more than one dot, in which case only the bit after the final one should be the suffix.

A: 

if this="what.to.do" you can do this:

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

and you'll get back

["", "what.to", "do"]
ennuikiller
The empty element there is a bit annoying, and you can't stick [1..2] at the end to fix it, since "whattodo".split(%r{(.+)\.}) returns ["whattodo"].
jpatokal
A: 

If you want the literal version of rsplit, you can do this (this is partly a joke, but actually works well):

"what.to.do".reverse.split('.', 2).map(&:reverse).reverse
=> ["what.to", "do"]
Peter
cool! but i can do this.split(%r{(.+)\.})[1,2] which gives the sme result
ennuikiller
there are indeed many ways.
Peter
+1  A: 

Here's what I'd actually do:

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

or perhaps more conventionally,

s = "what.to.do"

s.match(/(.*)\.(.*)/)[1..2]
=> ["what.to", "do"]
Peter
I agree but I assumed he wanted a solution with split :)
ennuikiller
Otherwise nice, but fails when s does not contain a dot.
jpatokal
A: 

Put on the thinking cap for a while and came up with this regexp:

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

Or in human terms "split at dot, not followed by another dot, at end of string". Works nicely also with dotless strings and sequences of dots:

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

I'm surprised nobody pointed out the String method that does just that:

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

It's in Ruby 1.9 (and upcoming in 1.8.8) only, though, so if running an earlier version:

require 'backports'
Marc-André Lafortune