【问题标题】:Rails: Smart text truncationRails:智能文本截断
【发布时间】:2009-08-18 12:41:40
【问题描述】:

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

例如:

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

【问题讨论】:

    标签: ruby-on-rails ruby text truncate


    【解决方案1】:

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

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

    【讨论】:

    • 哦,这是一个非常好的答案!非常感谢!现在我看到了增加正则表达式知识的真正理由。
    • 它不能像预期的那样处理句子。它在句子之间增加了很多分隔符(点)。
    • 这工作:return s.split(/\.(\s|$)+/).reject{ |s| s.strip.empty? }[0, opts[:sentences]].map{|s| s.strip}.join('. ') + '...'
    • 节省时间!感谢您的帮助。
    【解决方案2】:

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

    【讨论】:

    • 目前在字符数中不包括空格。如果你想考虑空格,它应该有 size += token.size + 1。
    • 你应该编辑你的答案,在问号前加入空格,作为 if else 语句语法错误的简短语法。
    • 我已经编辑了上面的代码以反映 cmets 中提到的错误。它似乎在我的系统上正常工作
    【解决方案3】:

    宝石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>
    

    【讨论】:

      【解决方案4】:

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

      更新:采用上面的代码并对其进行了一些更新。对于旧的 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
      

      【讨论】:

      • 实际上查看 soulofpeace 代码,它确实允许使用 utf8 和 mb_chars。所以我拿了他的代码,做了一点改进。
      【解决方案5】:

      我已经为不同项目的一些更新工作了很长一段时间,我想出了这些代码的改进,这些改进似乎在现实生活场景中更有用。

      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
      

      【讨论】:

      • 如果您愿意,也可以使用ActionController::Base.helpers.strip_tags(text) 删除可能与该文本一起传递的任何标签。
      猜你喜欢
      • 1970-01-01
      • 2010-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-28
      • 2020-09-30
      相关资源
      最近更新 更多