截断字符串的一部分以限制Ruby中整个字符串的长度

时间:2010-06-06 21:09:45

标签: ruby string

假设您要生成如下所示的动态页面标题:

“这完全是一个梦想,我曾经从”臭名昭着的B.I.G

“Juicy”读起来的杂志

即来自艺术家“SONG_NAME”的“LYRICS”

但是,您的标题总共只能为69个字符,此模板有时会生成更长的标题。

解决此问题的一种策略是将整个字符串截断为69个字符。但是,更好的方法是首先截断字符串中较不重要的部分。即,您的算法可能如下所示:

  1. 截断歌词,直到整个字符串为<= 69个字符
  2. 如果您仍然需要截断,请截断艺术家名称,直到整个字符串为&lt; = 69个字符
  3. 如果仍然需要截断,请截断歌曲名称,直到整个字符串为&lt; = 69个字符
  4. 如果所有其他方法都失败,请将整个字符串截断为69个字符
  5. 理想情况下,算法还会限制字符串的每个部分被截断的数量。例如,第1步实际上是“将歌词截断至少10个字符,直到整个字符串为&lt; = 69个字符”

    由于这是一种常见的情况,我想知道某人是否有可以处理它的库或代码片段。

2 个答案:

答案 0 :(得分:0)

我在截断标题时遇到了类似的问题,将它们放入推文中。我最终把所有东西放在一个数组中并加入它。代码具有合理的可读性。这是一个经过修改的版本,可以满足您的需求。

message = [lyrics, " from ", song_name, " by ", artist]
[0, 2, 4].each do |index|
  length = message.join.length
  message[index] = message[index][0...(69-length)]
end
message = message.join

您可能还希望在截断时附加省略号,以便人们知道它已被删除。

答案 1 :(得分:0)

这是一个相当完整的实施

#!/usr/bin/ruby

MIN_WORD_SIZE = 10
MAX_STRING_SIZE = 55  # 69 - 14 characters for punctuation spacing and conjunctions

def smart_trunc_words(lyrics, artist, title)

  words = [lyrics, artist, title]

  words.each_index do |idx|
    total_length = words.to_s.length
    if ( words[idx].length > MIN_WORD_SIZE and total_length > MAX_STRING_SIZE )
      other_words = total_length - words[idx].length
      max_word_size = [MAX_STRING_SIZE - other_words, MIN_WORD_SIZE].max
      words[idx] = truncate_word words[idx], max_word_size
    end
  end

  words

end

def truncate_word(word, sub_size)
  # Enhance by adding ellipses here or break on a word boundary
  word[0, sub_size]

end

def smart_trunc(lyrics, artist, title)
  lyrics, artist, title  = smart_trunc_words lyrics, artist, title
  '"%s" from "%s" by %s' % [lyrics, title, artist]
end

test_data = [
  [ "It was all a dream, I used to read word up magazine",  "The Notorious B.I.G", "Juicy"],
  [ "Ground Control to Major Tom, your circuits dead there's something wrong",  "David Bowie", "Space Oddity"],
  [ "Back Home they'll be thinking about us", "The England world cup squad (1970)" , "Back Home"],
  [ "I'm the new cancer", "Panic at the disco", "Theres A Good Reason These Tables Are Numbered Honey, You Just Havent Thought Of It Yet"],
  [ "Short lyrics", "short band", "short song"],
  [ "VeryLongLyrics VeryLongLyrics VeryLongLyrics VeryLongLyrics VeryLongLyrics",
    "VeryLongBandName VeryLongBandName VeryLongBandName VeryLongBandName VeryLongBandName",
    "VeryLongTitle VeryLongTitle VeryLongTitle VeryLongTitle VeryLongTitle"]
]


test_data.each do |td|
  lyrics = td[0]
  artist = td[1]
  title = td[2]
  puts 'Original string : "%s" from "%s" by %s' % [lyrics, title, artist]
  puts "New string      : #{smart_trunc lyrics, artist, title}"
end

产生以下结果

Original string : "It was all a dream, I used to read word up magazine" from "Juicy" by The Notorious B.I.G
New string      : "It was all a dream, I used to r" from "Juicy" by The Notorious B.I.G
Original string : "Ground Control to Major Tom, your circuits dead there's something wrong" from "Space Oddity" by David Bowie
New string      : "Ground Control to Major Tom, you" from "Space Oddity" by David Bowie
Original string : "Back Home they'll be thinking about us" from "Back Home" by The England world cup squad (1970)
New string      : "Back Home th" from "Back Home" by The England world cup squad (1970)
Original string : "I'm the new cancer" from "Theres A Good Reason These Tables Are Numbered Honey, You Just Havent Thought Of It Yet" by Panic at the disco
New string      : "I'm the ne" from "Theres A Good Reason These Tables A" by Panic at t
Original string : "Short lyrics" from "short song" by short band
New string      : "Short lyrics" from "short song" by short band
Original string : "VeryLongLyrics VeryLongLyrics VeryLongLyrics VeryLongLyrics VeryLongLyrics" from "VeryLongTitle VeryLongTitle VeryLongTitle VeryLongTitle VeryLongTitle" by VeryLongBandName VeryLongBandName VeryLongBandName VeryLongBandName VeryLongBandName
New string      : "VeryLongLy" from "VeryLongTitle VeryLongTitle VeryLon" by VeryLongBa

毫无疑问,一些红宝石大师会让它更短和/或更具惯用性