回答
这里是迈克伍德豪斯的回答修改后的版本。它需要2个可选参数:椭圆化字符串的最小长度和边长。
class String
def ellipsisize(minimum_length=4,edge_length=3)
return self if self.length < minimum_length or self.length <= edge_length*2
edge = '.'*edge_length
mid_length = self.length - edge_length*2
gsub(/(#{edge}).{#{mid_length},}(#{edge})/, '\1...\2')
end
end
"abc".ellipsisize #=> "abc"
"abcdefghi".ellipsisize #=> "abcdefghi"
"abcdefghij".ellipsisize #=> "abc...hij"
"abcdefghij".ellipsisize(4,4) #=> "abcd...ghij"
"Testing all paramas and checking them!".ellipsisize(6,5) #=> "Testi...them!"
Duh,我改变了我的意思,然后注意到你做了一个更完整的版本。尼斯。 +1 – 2009-09-21 08:19:21
可能我们应该将它作为补丁提交给Rails团队? – khelll 2009-09-22 04:15:53
相当复杂。利用现有的Rails'String'助手,查看我的答案,获得更简单的解决方案。 – 2013-10-13 14:12:17
由于您没有指定要截断的字符数,因此我假设(您的示例中)要截断长度大于6的字符串。然后你可以使用像这样的东西:
s = "Hello World, how are you?"
s = s[0, 3] + "..." + s[-3, 3] if s.length > 9
=> "Hel...ou?"
只需调整范围,如果你需要截断更多的字符。
DigitalRoss对“> 9”而不是“> 6”是正确的 - 如果你有一个长度为7的字符串,那么你添加了两个字符和丢失的信息。 – 2009-09-20 19:01:38
你是对的,忘了计算省略号的大小。现在已经修复了。 – 2009-09-20 22:43:58
这里是我的建议:
s[3...-4] = "..." if s.length > 9
我不太喜欢现场编辑,因为您不知道字符串来自哪里。如果它是一个模型属性,并且以后调用save,该怎么办? – 2009-09-20 19:00:34
是的,'(s = s.dup)[3 ...- 4] = ...'可能会更好,甚至在“作为黑箱”的观点中起作用。好点子。 – DigitalRoss 2009-09-20 20:02:27
你可能的意思是(t = s.dup)... there – 2009-09-20 21:02:00
怎么样一个正则表达式的版本:
class String
def ellipsisize
gsub(/(...).{4,}(...)/, '\1...\2')
end
end
"abc".ellipsisize #=> "abc"
"abcdefghi".ellipsisize #=> "abcdefghi"
"abcdefghij".ellipsisize #=> "abc...hij"
编辑:正如在评论中建议,参数化长度(以及使用不同的正则表达式的符号,只是为它赫克)
class String
def ellipsisize(len = 9)
len = 9 unless len > 9 # assumes minimum chars at each end = 3
gsub(%r{(...).{#{len-5},}(...)}, '\1...\2')
end
end
所以...
"abcdefghij".ellipsisize #=> "abc...hij"
但我们也可以:
"abcdefghij".ellipsisize(10) #=> "abcdefghij"
这解决了DigitalRoss和JG解决方案的问题。 +1 – 2009-09-20 19:08:25
非常好,尽管我只是为了方法的名称而提出了upvoted。 – Telemachus 2009-09-21 00:38:35
很酷,但如果你可以修改它以接受字符串长度参数,只有当字符串长于该长度时才应用截断,它会更好。 – khelll 2009-09-21 02:42:33
class String
# https://gist.github.com/1168961
# remove middle from strings exceeding max length.
def ellipsize(options={})
max = options[:max] || 40
delimiter = options[:delimiter] || "..."
return self if self.size <= max
remainder = max - delimiter.size
offset = remainder/2
(self[0,offset + (remainder.odd? ? 1 : 0)].to_s + delimiter + self[-offset,offset].to_s)[0,max].to_s
end unless defined? ellipsize
end
我添加位置选项,以粗俗的方法:
def ellipsize(str, options={})
max = options[:max] || 40
delimiter = options[:delimiter] || "..."
position = options[:position] || 0.8
return str if str.size <= max
remainder = max - delimiter.size
offset_left = remainder * position
offset_right = remainder * (1 - position)
(str[0,offset_left + (remainder.odd? ? 1 : 0)].to_s + delimiter + str[-offset_right,offset_right].to_s)[0,max].to_s
end
如果你想有一个特定的固定长度不考虑字符串的长度,你可以使用Rails的#truncate
:
s.truncate(100, omission: "...#{s.last(50)}")
太棒了。正是我在Google上搜索的内容。 – Ossie 2014-03-10 19:31:10
你应该得到我的赞赏。这是我正在寻找的。 – BartSabayton 2015-06-03 01:25:08
例如,如果字符串是110,省略号前后会重复很多字符。 – collimarco 2016-09-05 18:13:54
如果需要限制由bytesize您的字符串长度,你需要处理的unicode则列出的解决方案无法正常工作。
这是一个使用的字节大小,并保持统一文本元素不变(这并不总是相同为Unicode字符)的解决方案。经测试,在红宝石1.8/1.9/2.0。
对于需要截短到更小长度的非常长的字符串,可以对其进行改进以提高效率。
您必须安装unicode gem。
require 'unicode'
# truncates a unicode string like:
# >> truncate_string_middle('12345678', 5)
# => "1...8"
def truncate_string_middle(str, limit, ellipsis='...')
raise "limit (#{limit}) must not be less than the ellipsis size (#{ellipsis.bytesize})" if limit < ellipsis.bytesize
return str if str.bytesize <= limit
chars = Unicode.text_elements(str)
split_point = (chars.size/2.0).ceil
front, back = chars[0...split_point], chars[split_point..-1]
pop_front = chars.size.odd?
# alternate between popping from the front and shifting from the back until it's small enough
while (front.join + ellipsis + back.join).bytesize > limit
if pop_front
front.pop
else
back.shift
end
pop_front = !pop_front
end
front.join + ellipsis + back.join
end
另一种方式:
class String
def middle_truncate(len)
return self if len >= size
return self[0...len] unless len > 4
half = len/2.0
(result = dup)[(half - 1.5).floor...(1.5 - half).floor] = '...'
result
end
end
这样做的,如果字符串大小< 5只截断了额外的好处。
例如对于偶数大小的字符串:
2.1.1 :001 > s = "123456789"
=> "123456789"
2.1.1 :002 > s.middle_truncate 21
=> "123456789"
2.1.1 :003 > s.middle_truncate 20
=> "123456789"
2.1.1 :004 > s.middle_truncate 19
=> "12345678...34567890"
2.1.1 :005 > s.middle_truncate 18
=> "1234567...34567890"
2.1.1 :006 > s.middle_truncate 5
=> "1...0"
2.1.1 :007 > s.middle_truncate 4
=> "1234"
和奇数大小的字符串:
2.1.1 :012 > s = "123456789"
=> "123456789"
2.1.1 :013 > s.middle_truncate 22
=> "123456789"
2.1.1 :014 > s.middle_truncate 21
=> "123456789"
2.1.1 :015 > s.middle_truncate 20
=> "12345678...345678901"
2.1.1 :016 > s.middle_truncate 19
=> "12345678...45678901"
2.1.1 :017 > s.middle_truncate 5
=> "1...1"
2.1.1 :018 > s.middle_truncate 4
=> "1234"
这是最简单的方法对我来说:
def ellipsisize(text, minimum_length=12,edge_length=4)
leftover = text.length - minimum_length
edge_length = leftover if (edge_length > leftover && leftover >= 0)
edge_length = 0 if leftover < 0
return text.truncate(minimum_length) << text.last(edge_length)
end
问候乡亲!
- 1. 截断字符串
- 2. x个字符后截断字符串
- 3. 截断在python字符串
- 4. 字符串截断的ClientDataSet
- 5. RODBC字符串被截断
- 6. UILabel字符串截断
- 7. BufferedWriter将截断字符串
- 8. PHP截断字符串
- 9. Python截断长字符串
- 10. KRL:截断字符串
- 11. 如何在字符的第一个实例处截断字符串?
- 12. android spinners中的截断字符串
- 13. 在mvc homecontroller中截断字符串javascript
- 14. 截断sharepoint中的文本字符串
- 15. 如何在Java中的5分隔符后截断字符串?
- 16. 截断从最后一个字符串,直到一个字符在PHP
- 17. 如何防止PHP字符串在1997字符后截断
- 18. 按字节截断字符串
- 19. 如何截断codeigniter视图中的字符串
- 20. 如何截断PHP中的UTF8字符串?
- 21. 如何高效截断字符串中的填充零点
- 22. 如何...截断数组中的字符串
- 23. 如何截断PHP中的分隔字符串?
- 24. 如何禁用SQL Server中的字符串截断错误?
- 25. 如何防止在单元测试中截断字符串python
- 26. 如何在Silverlight TextBlock中使用省略号截断字符串?
- 27. reg表达式截断最后一个点的字符串
- 28. 用JQuery截断一个字符串并设置回元素
- 29. 截断字符串逃过forien charasters
- 30. C:strncpy意外截断字符串
你想要截断多少个字符? – 2009-09-20 16:32:09
使用rails需要您了解一些中级编程主题和Ruby语言。这就是为什么我不明白你的问题是什么 - 这很容易实现。有些人可能会争论使用助手,或猴子补丁'字符串类,但*解*很简单。 – samuil 2009-09-21 13:15:22