Skip to content

Commit

Permalink
string-rpartition from fresh upstream
Browse files Browse the repository at this point in the history
johnjansen authored and Ary Borenszweig committed Oct 20, 2016

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent 2616769 commit 186dfd2
Showing 2 changed files with 84 additions and 0 deletions.
26 changes: 26 additions & 0 deletions spec/std/string_spec.cr
Original file line number Diff line number Diff line change
@@ -657,6 +657,32 @@ describe "String" do
end
end

describe "rpartition" do
describe "by char" do
"hello".rpartition('l').should eq ({"hel", "l", "o"})
"hello".rpartition('o').should eq ({"hell", "o", ""})
"hello".rpartition('h').should eq ({"", "h", "ello"})
end

describe "by string" do
"hello".rpartition("l").should eq ({"hel", "l", "o"})
"hello".rpartition("x").should eq ({"", "", "hello"})
"hello".rpartition("o").should eq ({"hell", "o", ""})
"hello".rpartition("h").should eq ({"", "h", "ello"})
"hello".rpartition("ll").should eq ({"he", "ll", "o"})
"hello".rpartition("lo").should eq ({"hel", "lo", ""})
"hello".rpartition("he").should eq ({"", "he", "llo"})
end

describe "by regex" do
"hello".rpartition(/.l/).should eq ({"he", "ll", "o"})
"hello".rpartition(/ll/).should eq ({"he", "ll", "o"})
"hello".rpartition(/.o/).should eq ({"hel", "lo", ""})
"hello".rpartition(/.e/).should eq ({"", "he", "llo"})
"hello".rpartition(/l./).should eq ({"hel", "lo", ""})
end
end

describe "byte_index" do
assert { "foo".byte_index('o'.ord).should eq(1) }
assert { "foo bar booz".byte_index('o'.ord, 3).should eq(9) }
58 changes: 58 additions & 0 deletions src/string.cr
Original file line number Diff line number Diff line change
@@ -2239,6 +2239,64 @@ class String
{pre, mid, post}
end

# Searches sep or pattern (regexp) in the string from the end of the string,
# and returns the part before it, the match, and the part after it.
# If it is not found, returns two empty strings and str.
#
# ```
# "hello".rpartition("l") # => {"hel", "l", "o"}
# "hello".rpartition("x") # => {"", "", "hello"}
# "hello".rpartition(/.l/) # => {"he", "ll", "o"}
# ```
def rpartition(search : (Char | String)) : Tuple(String, String, String)
pos = self.rindex(search)
search_size = search.is_a?(Char) ? 1 : search.size

pre = mid = post = ""

case pos
when .nil?
post = self
when 0
mid = search.to_s
post = self[(pos + search_size)..-1]
else
pre = self[0..(pos - 1)]
mid = search.to_s
post = self[(pos + search_size)..-1]
end
{pre, mid, post}
end

# ditto
def rpartition(search : Regex) : Tuple(String, String, String)
match_result = nil
pos = self.size - 1

while pos >= 0
self[pos..-1].scan(search) do |m|
match_result = m
end
break unless match_result.nil?
pos -= 1
end

pre = mid = post = ""

case
when match_result.nil?
post = self
when pos == 0
mid = match_result[0]
post = self[match_result[0].size..-1]
else
pre = self[0..pos - 1]
mid = match_result.not_nil![0]
post = self[pos + match_result.not_nil![0].size..-1]
end
{pre, mid, post}
end

def byte_index(byte : Int, offset = 0)
offset.upto(bytesize - 1) do |i|
if to_unsafe[i] == byte

0 comments on commit 186dfd2

Please sign in to comment.