Обрезать части строки, чтобы ограничить длину всей строки в Ruby - PullRequest
0 голосов
/ 07 июня 2010

Предположим, вы хотите создать динамические заголовки страниц, которые выглядят следующим образом:

"Это был весь сон, я привык читать журнал" из "Juicy" от The Notorious B.I.G

Т.е., "LYRICS" из "SONG_NAME" от ARTIST

Тем не менее, ваш заголовок может содержать не более 69 символов, и этот шаблон иногда генерирует более длинные заголовки.

Одной из стратегий решения этой проблемы является урезание всей строки до 69 символов. Тем не менее, лучший подход - сначала обрезать менее важные части строки. Т.е. ваш алгоритм может выглядеть примерно так:

  1. Обрезать текст до тех пор, пока вся строка не станет <= 69 символов </li>
  2. Если вам все еще нужно обрезать, обрезайте имя исполнителя, пока вся строка не станет <= 69 символов </li>
  3. Если вам по-прежнему нужно усечь, сокращайте название песни до тех пор, пока вся строка не станет <= 69 символов </li>
  4. Если ничего не помогает, обрежьте всю строку до 69 символов

В идеале алгоритм также должен ограничивать количество, которое каждая часть строки может быть обрезана. Например, шаг 1 действительно будет «Обрезать текст до минимум 10 символов, пока вся строка не будет <= 69 символов» </p>

Поскольку это такая распространенная ситуация, мне было интересно, есть ли у кого-нибудь библиотека или фрагмент кода, который может позаботиться об этом.

Ответы [ 2 ]

0 голосов
/ 08 июня 2010

Это достаточно полная реализация

#!/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

Без сомнения, некоторые из рубиновых гуру сделают его короче и / или более идиоматическим

0 голосов
/ 07 июня 2010

У меня была похожая проблема с усечением заголовков, чтобы поместить их в твит. Я закончил тем, что поместил все в массив и присоединился к нему. Код достаточно читабелен. Вот версия, которая модифицирована для того, что вы ищете.

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

Вы также можете добавить многоточие при усечении, чтобы люди знали, что оно обрезано.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...