From 48116ef8d81ddba1faa05c11845618c1442c23f2 Mon Sep 17 00:00:00 2001 From: Andy Stewart Date: Mon, 6 Apr 2009 09:06:33 +0100 Subject: [PATCH] Unicode-aware rindex method. --- .../lib/active_support/multibyte/chars.rb | 12 ++++++++++++ activesupport/test/multibyte_chars_test.rb | 10 ++++++++++ 2 files changed, 22 insertions(+), 0 deletions(-) diff --git a/activesupport/lib/active_support/multibyte/chars.rb b/activesupport/lib/active_support/multibyte/chars.rb index 60f082b..f1dbca1 100644 --- a/activesupport/lib/active_support/multibyte/chars.rb +++ b/activesupport/lib/active_support/multibyte/chars.rb @@ -208,6 +208,18 @@ module ActiveSupport #:nodoc: index = @wrapped_string.index(needle, offset) index ? (self.class.u_unpack(@wrapped_string.slice(0...index)).size) : nil end + + # Returns the position of the last occurrence of _needle_ in the string, + # counting in codepoints. Returns +nil+ if _needle_ isn't found. + def rindex(needle, stop=nil) + if stop.nil? || stop > size + stop = size + elsif stop < 0 + stop = size + stop + end + reverse_index = slice(0...stop).reverse.index(needle.mb_chars.reverse) + reverse_index.nil? ? nil : stop - needle.mb_chars.size - reverse_index + end # Like String#[]=, except instead of byte offsets you specify character offsets. # diff --git a/activesupport/test/multibyte_chars_test.rb b/activesupport/test/multibyte_chars_test.rb index 661b33c..8aea0c4 100644 --- a/activesupport/test/multibyte_chars_test.rb +++ b/activesupport/test/multibyte_chars_test.rb @@ -234,6 +234,16 @@ class MultibyteCharsUTF8BehaviourTest < Test::Unit::TestCase assert_equal 3, @chars.index('わ') end + def test_rindex_should_return_character_offset + assert_nil @chars.rindex('u') + assert_equal 0, @chars.rindex('こに') + assert_equal 2, @chars.rindex('ち') + assert_equal 2, @chars.rindex('ち', -1) + assert_nil @chars.rindex('ち', -2) + assert_equal 3, @chars.rindex('わ') + assert_nil @chars.rindex('わ', 2) + end + def test_indexed_insert_should_take_character_offsets @chars[2] = 'a' assert_equal 'こにaわ', @chars -- 1.6.0.2