从Ruby字符串中提取最后n个字符

119

要从字符串中获取最后 n 个字符,我认为可以使用

ending = string[-n..-1]

但如果字符串长度小于n,则会返回nil

有哪些解决方法?

背景:这些字符串是普通ASCII码,并且我可以访问Ruby 1.9.1,我正在使用普通的Ruby对象(没有Web框架)。

9个回答

124

嗯,我能想到的最简单的解决方法是:

ending = str[-n..-1] || str

(编辑:逻辑或运算符的优先级低于赋值运算符,因此请确保使用||代替or。)


+1... 我认为这种方式比 string.reverse[0..n].reverse 更易于阅读,否则我会停留一秒钟,问自己:“他为什么要那样做?”(或者如果我不是在读这个问题的情况下的话) - Arkaaito
4
еҘҪзҡ„еӣһзӯ”пјҢдҪҶеә”иҜҘдҪҝз”Ё||д»ЈжӣҝorпјҢжҲ–иҖ…еңЁstr[-n..-1] or strе‘ЁеӣҙеҠ дёҠжӢ¬еҸ·гҖӮ - Andrew Grimm
不错的答案,但我不喜欢 Ruby 对 s[-inf..-1] 和 x[0..inf] 的处理不同。 - klochner
谢谢你注意到操作符优先级的问题,安德鲁。这个问题每次都会让我犯错。 - perimosocordiae
@perimosocordiae 你并不是唯一一个。https://dev59.com/I3RC5IYBdhLWcg3wOOT1 - Andrew Grimm
我喜欢这个解决方案,因为[]在字符串的任何位置上都非常灵活操作。 - Donato

112

这里有一个一行式的代码,你可以在其中输入一个大于字符串长度的数字:

"123".split(//).last(5).to_s

针对 Ruby 1.9 及以上版本

"123".split(//).last(5).join("").to_s

对于 Ruby 2.0+,join 方法返回一个字符串

"123".split(//).last(5).join

23
如果您正在使用较新版本的Ruby,您可以使用chars代替split - Andrew Grimm
1
我使用了 "12345678910".split(//).last(7).join.to_s。 - Hard-Boiled Wonderland
@Hard-BoiledWonderland join函数可以使用。如果你使用了join,我认为你不需要最后的to_s - Andrew Grimm
你缺少了 .join - 现在它返回一个字符串数组。相反,应该是 "123".split(//).last(5).join(Ruby 2.0.0)。 - Pavel Nikolov
如果你正在使用Rails,ActiveSupport定义了String#last函数:http://api.rubyonrails.org/classes/String.html#method-i-last - Gabe Martin-Dempesy
显示剩余2条评论

77

在不使用Rails的纯Ruby中,你可以这样做:

string.chars.last(n).join

例如:

2.4.1 :009 > a = 'abcdefghij'
 => "abcdefghij"
2.4.1 :010 > a.chars.last(5).join
 => "fghij"
2.4.1 :011 > a.chars.last(100).join
 => "abcdefghij"
如果你在使用Ruby on Rails,你可以在字符串对象上调用方法firstlast。这些方法因为简洁易懂而被推荐使用。
例如:
[1] pry(main)> a = 'abcdefg'                                                                                                                
 => "abcdefg"
[2] pry(main)> a.first(3)                                                                                                                   
 => "abc"
[3] pry(main)> a.last(4)                                                                                                                    
 => "defg"

1
Ruby并不意味着Rails。 - Volte

14
ending = string.reverse[0...n].reverse

这是我在这个页面上看到的最好的方法,它满足了能够提供超过总字符串长度的结束字符长度的要求。 - Rob.Kachmar
1
例如,如果您打算提取一组字符串的最后3个字符,如“abcde”、“ab”和“a”。使用相同的代码,该技术将导致“cde”、“ab”和“a”。 "abcde".reverse[0,3].reverse >>> "cde" "ab".reverse[0,3].reverse >>> "ab" "a".reverse[0,3].reverse >>> "a" - Rob.Kachmar

10
您可以使用以下代码:

您可以使用以下代码:

string[string.length-n,string.length]

1
只翻译程序相关内容,不要加入机器翻译的风格。请返回纯文本翻译:仅代码 - 简单回答并不能解决问题,最好能够解释这段代码是如何修复问题的。 - ry8806

6
要从字符串中获取最后n个字符,您可以执行以下操作:

如果a是数组,那么就使用a[-n, n]。

这里有一个例子供您参考:

ruby-1.9.2-p180 :006 > a = "911234567890"

=> "911234567890"

ruby-1.9.2-p180 :009 > a[-5,5]

=> "67890"

ruby-1.9.2-p180 :010 > a[-7,7]

=> "4567890"


如果数字太大,将返回nil,而这正是该问题特别想避免的。 - Andrew Grimm
好的答案。简洁明了。 - Volte
为什么这个得到了点赞?它和 OP 提出的需要解决的问题完全一样。 - jeffdill2

5

你尝试过使用正则表达式吗?

string.match(/(.{0,#{n}}$)/)
ending=$1

正则表达式尽可能捕获字符串末尾的多个字符,但不超过n个,并将其存储在$1中。

2

对于那些使用Ruby on Rails的人,你可以简单地这样做:

str.last(n)

注意:我意识到这并没有回答提问者的问题,因为在纯 Ruby(不使用 Rails)中,last 方法不存在于 String。对此,这里有许多其他很好的回答。

2
last 方法在 String 中不存在。您应该删除此答案。 - Casper

1

对EmFi的回答进行改进。

string[/.{,#{n}}\z/m]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接