我想知道是否有一个插件可以启用某种智能截断。我需要用一个单词或一个句子的精确度截断我的文本。
例如:
Post.my_message.smart_truncate(
"Once upon a time in a world far far away. And they found that many people
were sleeping better.", :sentences => 1)
# => Once upon a time in a world far far away.
或
Post.my_message.smart_truncate(
"Once upon a time in a world far far away. And they found that many people
were sleeping better.", :words => 12)
# => Once upon a time in a world far far away. And they ...
答案 0 :(得分:20)
我没有看过这样的插件,但有一个similar question可以作为lib或帮助函数的基础。
你展示函数的方式似乎把它作为String的扩展:除非你真的希望能够在视图之外做到这一点,否则我倾向于在application_helper.rb
中找到一个函数。也许是这样的事情?
module ApplicationHelper
def smart_truncate(s, opts = {})
opts = {:words => 12}.merge(opts)
if opts[:sentences]
return s.split(/\.(\s|$)+/)[0, opts[:sentences]].map{|s| s.strip}.join('. ') + '.'
end
a = s.split(/\s/) # or /[ ]+/ to only split on spaces
n = opts[:words]
a[0...n].join(' ') + (a.size > n ? '...' : '')
end
end
smart_truncate("a b c. d e f. g h i.", :sentences => 2) #=> "a b c. d e f."
smart_truncate("apple blueberry cherry plum", :words => 3) #=> "apple blueberry cherry..."
答案 1 :(得分:8)
这将根据指定的char_limit长度截断单词边界。所以它不会在奇怪的地方截断句子
def smart_truncate(text, char_limit)
size = 0
text.split().reject do |token|
size += token.size() + 1
size > char_limit
end.join(' ') + ( text.size() > char_limit ? ' ' + '...' : '' )
end
答案 2 :(得分:1)
gem truncate_html完成这项工作。它还可以跳过HTML片段 - 这可能非常有用 - 并提供自定义单词边界正则表达式的可能性。此外,可以在config/environment.rb
。
示例:强>
some_html = '<ul><li><a href="http://whatever">This is a link</a></li></ul>'
truncate_html(some_html, :length => 15, :omission => '...(continued)')
=> <ul><li><a href="http://whatever">This...(continued)</a></li></ul>
答案 3 :(得分:0)
好帮手。由于我有不同的经历,我确实改变了它,以便它停在最后一个单词并使用字符限制。我认为在大多数应用程序中这是更真实的场景。
更新:取了上面的代码并稍微更新了一下。对于旧红宝石看起来更好的方法,并使用utf8。
def smart_truncate(text, char_limit)
text = text.squish
size = 0
text.mb_chars.split().reject do |token|
size+=token.size()
size>char_limit
end.join(" ")
end
答案 4 :(得分:0)
现在在不同项目的一些更新上工作了一段时间,我想出了这些在现实生活场景中看起来更有用的代码改进。
def smart_truncate_characters(text, char_limit)
text = text.to_s
text = text.squish
size = 0
new_text = text.mb_chars.split().reject do |token|
size+=token.size()
size>char_limit
end.join(" ")
if size > char_limit
return new_text += '…'
else
return new_text
end
end
def smart_truncate_sentences(text, sentence_limit)
text = text.to_s
text = text.squish
size = 0
arr = text.mb_chars.split(/(?:\.|\?|\!)(?= [^a-z]|$)/)
arr = arr[0...sentence_limit]
new_text = arr.join(".")
new_text += '.'
end
def smart_truncate(text, sentence_limit, char_limit)
text = smart_truncate_sentences(text, sentence_limit)
text = smart_truncate_characters(text, char_limit)
end