Rails:智能文本截断

发布于 2024-08-02 03:22:53 字数 555 浏览 3 评论 0原文

我想知道是否有一个插件可以启用某种智能截断。 我需要以单词或句子的精度截断文本。

例如:

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 ...

I wonder if there's a plugin to enable a sort of smart truncation. I need to truncate my text with a precision of a word or of a sentence.

For example:

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.

or

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 ...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

绝不服输 2024-08-09 03:22:53

我还没有见过这样的插件,但是有一个类似的问题可以作为库或辅助函数的基础。

您显示该函数的方式似乎将其作为 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..."

I haven't seen such a plugin, but there was a similar question that could serve as the basis for a lib or helper function.

The way you show the function seems to put it as an extension to String: unless you really want to be able to do this outside of a view, I'd be inclined to go for a function in application_helper.rb. Something like this, perhaps?

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..."
む无字情书 2024-08-09 03:22:53

这将根据指定的 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

This will truncate at the word boundary based on the char_limit length specified. So it will not truncate the sentence at weird places

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
沩ん囻菔务 2024-08-09 03:22:53

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>

The gem truncate_html does this job. It also can skip over pieces of HTML – which can be quiet useful – and offers the possibility to customize the word boundary regex. Furthermore the defaults for all parameters can be configured eg in your config/environment.rb.

Example:

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>
诗酒趁年少 2024-08-09 03:22:53

好帮手。 由于我有不同的经历,我确实对其进行了更改,以便它在最后一个单词处停止并使用字符限制。 我认为这在大多数应用程序中都是更真实的场景。

更新:采用上面的代码并对其进行了一些更新。 对于旧的 ruby​​ 来说似乎更好,并且可以与 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

Nice helper. Since I had a different experience I did change it so that it stops on the last word and work with character limit. I think this is much more real world scenario in most apps.

Update: Took the code above and updated it a bit. Seemed much nicer approach for old ruby and works with 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
我只土不豪 2024-08-09 03:22:53

现在,我在不同项目的一些更新上工作了相当长的一段时间,我对代码进行了这些改进,这些改进在现实生活场景中似乎更有用。

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

Working for quite a while now on some updates with different projects and I came up with these refinements of the code that seem much more usable in real life scenarios.

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文