【问题标题】:Get first N characters from string without cutting the whole words从字符串中获取前 N 个字符而不剪切整个单词
【发布时间】:2013-05-06 10:17:36
【问题描述】:

我想知道是否有一种简单的方法可以从字符串中只获取 N 个符号而不切割整个单词。

例如,我有产品和产品描述信息。描述长度从 70 到 500 个符号,但我只想显示前 70 个符号,如下所示:

可口可乐是世界上最受欢迎和最畅销的软饮料 历史,以及世界上最知名的品牌。

2011 年 5 月 8 日,可口可乐庆祝成立 125 周年。创建于 1886 年,可口可乐在佐治亚州亚特兰大市由约翰·彭伯顿博士(Dr. John S. Pemberton) Jacob's Pharmacy 首次作为喷泉饮料提供 可口可乐糖浆加碳酸水。

所以,普通的子字符串方法会给我:

Coca-Cola is the most popular and biggest-selling soft drink in histor

我需要一个方法来获得这个:

Coca-Cola is the most popular and biggest-selling soft drink in ...

【问题讨论】:

  • 符号?你的意思是“字符”吗?

标签: ruby ruby-on-rails-3 jruby substring words


【解决方案1】:

只需使用带有分隔符选项的截断:

truncate("Once upon a time in a world far far away", length: 17)
# => "Once upon a ti..."
truncate("Once upon a time in a world far far away", length: 17, separator: ' ')
# => "Once upon a..."

获取更多信息:truncate helper in rails API documentation

【讨论】:

  • '曾几何时在遥远的世界'.truncate(17, separator: ' ')
【解决方案2】:

此方法使用正则表达式,它贪婪地抓取多达 70 个字符,然后匹配空格或字符串结尾来完成您的目标

def truncate(s, max=70, elided = ' ...')
  s.match( /(.{1,#{max}})(?:\s|\z)/ )[1].tap do |res|
    res << elided unless res.length == s.length
  end    
end

s = "Coca-Cola is the most popular and biggest-selling soft drink in history, as well as the best-known brand in the world."
truncate(s)
=> "Coca-Cola is the most popular and biggest-selling soft drink in ..."

【讨论】:

  • 我很难理解这个解决方案。你能告诉我发生了什么事吗?
  • @JakeSmith 我们将 s 字符串匹配为可能被正则表达式模式截断。该模式由一个子句组成,该子句贪婪地将任何字符(.{1,#{max}}) 的最大重复次数匹配为 1 个到最大重复作为捕获组,然后是一个子句对空白字符或字符串结尾 (?:\s|\z) 进行非捕获匹配。匹配结果上的[1] 提取第一个捕获。如果该捕获比整个字符串短,它会附加省略号。
  • 注意,当第一个最大字符中没有空格或字符串结尾时,这可能无法按预期工作。例如。 truncate(s, 3) 结果是“ola ...”而不是“Col ...”或者可能只是“...”。如果在这种情况下您希望获得前 n 个字符,请参阅下面的启发式解决方案。
【解决方案3】:
s = "Coca-Cola is the most popular and biggest-selling soft drink in history, as well as the best-known brand in the world."
s = s.split(" ").each_with_object("") {|x,ob| break ob unless (ob.length + " ".length + x.length <= 70);ob << (" " + x)}.strip
#=> "Coca-Cola is the most popular and biggest-selling soft drink in"

【讨论】:

    【解决方案4】:
    s[0..65].rpartition(" ").first << " ..."
    

    在你的例子中:

    s = "Coca-Cola is the most popular and biggest-selling soft drink in history, as well as the best-known brand in the world."    
    t = s[0..65].rpartition(" ").first << " ..."
    => "Coca-Cola is the most popular and biggest-selling soft drink in ..." 
    

    【讨论】:

    • 很好,但是如果句子没有空格,会返回"..."
    【解决方案5】:

    (受 dbenhur 的回答启发,但更好地处理前最大字符中没有空格或字符串结尾的情况。)

    def truncate(s, options = { })
      options.reverse_merge!({
         max: 70,
         elided: ' ...'
      });
    
      s =~ /\A(.{1,#{options[:max]}})(?:\s|\z)/
      if $1.nil? then s[0, options[:max]] + options[:elided]
      elsif $1.length != s.length then $1 + options[:elided]
      else $1
      end
    end
    

    【讨论】:

      【解决方案6】:
      b="Coca-Cola is the most popular and biggest-selling soft drink in history, as well "
      
      def truncate x
      a=x.split("").first(70).join
      
      w=a.split("").map!.with_index do |x,y|
          if x!=" "
              x=nil
          else
              x=y
          end
      end
      w.compact!
      index=w.last
      
      x.split("").first(index).join+" ..."
      end
      
      truncate b
      

      【讨论】:

        猜你喜欢
        • 2022-08-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-03-15
        • 2011-07-24
        • 1970-01-01
        相关资源
        最近更新 更多