Если вам нужно ограничить длину строки байтовым размером и вам нужно обрабатывать юникод, то перечисленные решения не будут работать правильно.
Вот решение, которое использует размер в байтах и сохраняет Unicode текстовые элементы без изменений (которые не всегда совпадают с Unicode символами ). Протестировано в Ruby 1.8 / 1.9 / 2.0.
Это может быть улучшено, чтобы быть более эффективным для очень длинных строк, которые должны быть обрезаны до гораздо меньшей длины.
Вы должны установить гем Юникода.
require 'unicode'
# truncates a unicode string like:
# >> truncate_string_middle('12345678', 5)
# => "1...8"
def truncate_string_middle(str, limit, ellipsis='...')
raise "limit (#{limit}) must not be less than the ellipsis size (#{ellipsis.bytesize})" if limit < ellipsis.bytesize
return str if str.bytesize <= limit
chars = Unicode.text_elements(str)
split_point = (chars.size/2.0).ceil
front, back = chars[0...split_point], chars[split_point..-1]
pop_front = chars.size.odd?
# alternate between popping from the front and shifting from the back until it's small enough
while (front.join + ellipsis + back.join).bytesize > limit
if pop_front
front.pop
else
back.shift
end
pop_front = !pop_front
end
front.join + ellipsis + back.join
end