【发布时间】:2016-06-05 17:33:30
【问题描述】:
如何将一个字符串拆分为多个长度相等但从后面开始的子字符串?
例如如果字符串是:"ABCDEFGH",那么我想要每个长度为 3 的字符串的数组为:
["FGH", "CDE", "AB"]
【问题讨论】:
标签: ruby string split substring slice
如何将一个字符串拆分为多个长度相等但从后面开始的子字符串?
例如如果字符串是:"ABCDEFGH",那么我想要每个长度为 3 的字符串的数组为:
["FGH", "CDE", "AB"]
【问题讨论】:
标签: ruby string split substring slice
您可以使用each_slice 完成此操作,但您需要先反转字符串,然后重新反转每个单独的切片:
x = "ABCDEFGH"
x.chars.reverse.each_slice(3).map(&:reverse).map(&:join)
=> ["FGH", "CDE", "AB"]
x.chars).reverse).each_slice(3)).map(&:reverse)).map(&:join))【讨论】:
我认为这可以满足您的要求:
> "ABCDEFGH".reverse.scan(/.{1,3}/).each { |x| x.reverse! }
=> ["FGH", "CDE", "AB"]
这里有一个简单的解释:
.reverse 反转字符串,使其变为"HGFEDCBA" 而不是"ABCDEFGH"。
.scan(/.{1,3}/) 将字符串转换为数组,数组的每个元素包含 3 个字符(如果字符串不能被 3 整除,则数组的最后一个元素可能包含 1 或 2 个字符)。
.each { |x| x.reverse! } 反转数组每个元素中的字符。
你可以这样定义一个函数:
def slice_string_from_end(s)
s.reverse.scan(/.{1,3}/).each { |x| x.reverse! }
end
那么你可以使用:
slice_string_from_end("ABCDEFGH")
【讨论】:
"ABCDEFGH".scan(/.+?(?=(?:.{3})*\z)/) # => ["AB", "CDE", "FGH"]
"ABCDEFGH".scan(/.+?(?=(?:.{3})*\z)/).reverse # => ["FGH", "CDE", "AB"]
【讨论】:
您可以使用带有一些切片算法的while 循环:
s="ABCDEFGH"
li=[]
step=3
while s.length>0
ss=s[-(step<s.length ? step : s.length)..-1]
li << ss
s.chomp!(ss)
end
同样的方法适用于动态正则表达式:
s="ABCDEFGH"
li=[]
step=3
reg=".{1,#{step}}$"
while s.length>0
ss=s[/#{reg}/]
li << ss
s.delete_suffix!(ss)
end
两种情况:
> li
=> ["FGH", "CDE", "AB"]
【讨论】: