Skip to content

Instantly share code, notes, and snippets.

@JosephPecoraro
Created August 21, 2008 14:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JosephPecoraro/6563 to your computer and use it in GitHub Desktop.
Save JosephPecoraro/6563 to your computer and use it in GitHub Desktop.
Strip similarities at the start and end of two strings. [ruby]
# Strip Similarities between two strings
module Kernel
#
# strip_similiar
# Strips the similiarities at the start and end of each
# of the given strings, returning a list of both of the
# stripped strings.
#
# Example:
# strip_similiar( 'Ask Me Again', 'Ask You Again' ) #=> ['Me', 'You']
# strip_similiar( 'blah', 'blah' ) #=> [nil, nil]
# strip_similiar( 'foo', 'bar' ) #=> ['foo', 'bar']
#
def strip_similiar(left, right)
newLeft, newRight = strip_similiar_left(left, right)
strip_similiar_right( newLeft, newRight )
end
# Strip from the front
def strip_similiar_left(left, right)
return [left,right] if left.nil? or right.nil?
ceil = [left.length, right.length].min
pos = 0
pos.upto(ceil) do |i|
if left[i] == right[i]
pos += 1
else
break
end
end
pos -= 1 if pos > ceil
return [ left[pos, left.length], right[pos, right.length] ]
end
# Strip from the back
def strip_similiar_right(left, right)
return [left,right] if left.nil? or right.nil?
floor = [left.length, right.length].min
pos = -1
pos.downto(0-floor) do |i|
if left[i] == right[i]
pos -= 1
else
break
end
end
return [ left[0..pos], right[0..pos] ]
end
end
# Test Cases
require 'test/unit'
class StripTest < Test::Unit::TestCase
def test_left
assert_equal( strip_similiar_left(' xa', ' xb') , ['a','b'] )
assert_equal( strip_similiar_left('xxxa', 'xbbb'), ['xxa', 'bbb'] )
assert_equal( strip_similiar_left('a','a') , ['', ''] )
assert_equal( strip_similiar_left('This is a long test', 'This is a longer test'), [' test', 'er test'] )
end
def test_right
assert_equal( strip_similiar_right('ax ', 'bx ') , ['a','b'] )
assert_equal( strip_similiar_right('axxx', 'bbbx'), ['axx', 'bbb'] )
assert_equal( strip_similiar_right('a','a') , ['', ''] )
assert_equal( strip_similiar_right('This is a long test', 'This is a longer test'), ['This is a long', 'This is a longer'] )
end
def test_both
assert_equal( strip_similiar(' xa', ' xb') , ['a','b'] ) # Left
assert_equal( strip_similiar('xxxa', 'xbbb'), ['xxa', 'bbb'] ) # Left
assert_equal( strip_similiar('ax ', 'bx ') , ['a','b'] ) # Right
assert_equal( strip_similiar('axxx', 'bbbx'), ['axx', 'bbb'] ) # Right
assert_equal( strip_similiar('a','a') , ['', ''] ) # Empty
assert_equal( strip_similiar(' ', ' ') , [' ', ''] ) # Not exactly empty
assert_equal( strip_similiar('blah', 'blah'), ['', ''] ) # Code Example
assert_equal( strip_similiar('foo', 'bar') , ['foo', 'bar'] ) # Code Example
assert_equal( strip_similiar( 'Ask Me Again', 'Ask You Again' ), ['Me', 'You'] ) # Code Example
assert_equal( strip_similiar('This is a long test', 'This is a longer test'), ['', 'er'] ) # Longer
end
end
#
# Sadly this doesn't work for multi-byte encodings (Unicode, UTF-8, ...)
# Anyone care to implement that?
#
# I guess you should get each character, then compare chars, instead of comparing
# characters by the str[#] method that I am.
#
# I think its much easier in Ruby 1.9, so I'll hold off a little longer
#
# Example Test case for multibyte chars:
# é => 195, 169
# 195.chr.to_s => "\303"
# assert_equal( strip_similiar_left('é', 195.chr.to_s), ['é', "\303"] ) #=> FAILS
#
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment