用Rails截断字符串?

时间:2011-08-11 09:21:49

标签: ruby-on-rails ruby truncate

我想按如下方式截断字符串:

输入

string = "abcd asfsa sadfsaf safsdaf aaaaaaaaaa aaaaaaaaaa dddddddddddddd"

输出:

string = "abcd asfsa sadfsaf safsdaf aa...ddddd"

8 个答案:

答案 0 :(得分:93)

看看truncate,部分确实需要你想要的。如果你测试它是否被截断,你可以在截断的部分之后添加一些最后一部分。

truncate("Once upon a time in a world far far away")
# => "Once upon a time in a world..."

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("And they found that many people were sleeping better.", :length => 25, :omission => '... (continued)')
# => "And they f... (continued)"

答案 1 :(得分:14)

在最简单的情况下:

string = "abcd asfsa sadfsaf safsdaf aaaaaaaaaa aaaaaaaaaa dddddddddddddd"
tr_string = string[0, 20] + "..." + string[-5,5]

def trancate(string, length = 20)
  string.size > length+5 ? [string[0,length],string[-5,5]].join("...") : string
end

# Usage
trancate "abcd asfsa sadfsaf safsdaf aaaaaaaaaa aaaaaaaaaa dddddddddddddd"
#=> "abcd asfsa sadfsaf s...ddddd"
trancate "Hello Beautiful World"
#=> "Hello Beautiful World"
trancate "Hello Beautiful World", 5
#=> "Hello...World"

答案 2 :(得分:13)

如果没有Rails,你可以几乎

text.gsub(/^(.{50,}?).*$/m,'\1...')

50是您需要的长度。

答案 3 :(得分:9)

这可能不是您问题的确切解决方案,但我认为这将有助于让您朝着正确的方向前进,并采用相当简洁的方式。

如果你想要“Hello,World!”要限制在前五个字母,你可以这样做:

str = "Hello, World!"
str[0...5] # => "Hello"

如果你想要一个省略号,只需插入它:

"#{str[0...5]}..." #=> "Hello..."

答案 4 :(得分:8)

截断自定义省略

与其他人在此处提出的建议类似,您可以使用Rails的#truncate方法并使用实际上是字符串最后一部分的自定义省略:

string = "abcd asfsa sadfsaf safsdaf aaaaaaaaaa aaaaaaaaaa dddddddddddddd"

truncate(string, length: 37, omission: "...#{string[-5, 5]}")
# => "abcd asfsa sadfsaf safsdaf aa...ddddd"

正是你想要的。

奖励积分

您可能希望将其包含在一个名为truncate_middle的自定义方法中,该方法可以为您做一些花哨的步法:

# Truncate the given string but show the last five characters at the end.
#
def truncate_middle( string, options = {} )
  options[:omission] = "...#{string[-5, 5]}"    # Use last 5 chars of string.

  truncate( string, options )
end

然后就这样称呼它:

string = "abcd asfsa sadfsaf safsdaf aaaaaaaaaa aaaaaaaaaa dddddddddddddd"

truncate_middle( string, length: 37 )
# => "abcd asfsa sadfsaf safsdaf aa...ddddd"

轰!

感谢您询问此事。我认为这是展示较长文本片段的有用方式。

答案 5 :(得分:5)

这是String#truncate

的源代码
def truncate(truncate_at, options = {})
  return dup unless length > truncate_at

  options[:omission] ||= '...'
  length_with_room_for_omission = truncate_at - options[:omission].length
  stop = \
    if options[:separator]
      rindex(options[:separator], length_with_room_for_omission) ||      length_with_room_for_omission
    else
      length_with_room_for_omission
    end

   "#{self[0...stop]}#{options[:omission]}"
end

那么,至于你的情况

string.truncate(37, :omission => "...ddddd")

答案 6 :(得分:3)

这实际上是一个有趣的问题,你可能想用javascript而不是ruby来解决它。这就是为什么你可能会在屏幕上的某个地方显示这个文字,而你只有一定的宽度可用。因此,您不必将链接(或任何文本)缩减为多个字符,而是确保您显示的文本不会超过一定宽度。一定宽度可以容纳多少个字符取决于您正在使用的字体,间距等(css样式)。如果你使用的是基于ruby的解决方案,你可以确保一切正常,但是如果你决定稍后改变你的造型,它可能会全部落实。

所以,我建议使用基于javascript的解决方案。我以前处理它的方式是使用jquery truncate plugin。在您的应用中添加插件。然后在每次页面加载时挂钩一些类似于以下内容的javascript:

function truncateLongText() {
  $('.my_style1').truncate({
    width: 270,
    addtitle: true
  });
  $('.my_style2').truncate({
    width: 100
  });
}

添加其他任何需要截断的样式和它们应该尊重的宽度,插件完成其余的工作。这样做的另一个好处是可以将整个应用程序的所有截断逻辑放在一个方便的地方。

答案 7 :(得分:0)

对于只使用 RUBY 而不是 Rails 的人。

这是一个受@yegor256 的solution 启发的解决方案

def truncate(message, options = {})
  length = options[:length] || message.length
  return message unless message.length > length
  options[:omission] ||= '...'
  return message.gsub(/^(.{#{options[:length]},}?).*$/m, '\1'+options[:omission])
end

像这样使用:

truncate("your very very very long message", :length => 10)

您还可以提供带有 omission 选项的替换文本:

truncate("your very very very long message", :length => 10, :omission => '... more')