在Ruby中从末尾切片字符串

Posted

技术标签:

【中文标题】在Ruby中从末尾切片字符串【英文标题】:Slice string from end in Ruby 【发布时间】:2016-06-05 17:33:30 【问题描述】:

如何将一个字符串拆分为多个长度相等但从后面开始的子字符串?

例如如果字符串是:"ABCDEFGH",那么我想要每个长度为 3 的字符串的数组为:

["FGH", "CDE", "AB"]

【问题讨论】:

【参考方案1】:

您可以使用each_slice 完成此操作,但您需要先反转字符串,然后重新反转每个单独的切片:

x = "ABCDEFGH"
x.chars.reverse.each_slice(3).map(&:reverse).map(&:join)
=> ["FGH", "CDE", "AB"]
将字符串拆分为字符数组 (x.chars) 反转数组 (.reverse) 将数组分割成 3 个字符的子数组 (.each_slice(3)) 反转每个子数组 (.map(&:reverse)) 将每个子数组重新连接成一个字符串 (.map(&:join))

【讨论】:

【参考方案2】:

我认为这可以满足您的要求:

> "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")

【讨论】:

【参考方案3】:

splitscan 也可以,但就像@meagar 指出的那样,您需要反转然后重新反转字符串:

"ABCDEFGH".reverse.split(/(...)/).reject(&:empty?).map(&:reverse)
# => ["FGH", "CDE", "AB"]

扫描不需要寻找空字符串:

"ABCDEFGH".reverse.scan(/...?/).map(&:reverse)
# => ["FGH", "CDE", "AB"]

【讨论】:

【参考方案4】:
"ABCDEFGH".scan(/.+?(?=(?:.3)*\z)/) # => ["AB", "CDE", "FGH"]
"ABCDEFGH".scan(/.+?(?=(?:.3)*\z)/).reverse # => ["FGH", "CDE", "AB"]

【讨论】:

我不建议将它用于生产代码,它是一个强烈的正则表达式,但它确实很好用。【参考方案5】:

您可以使用带有一些切片算法的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"]

【讨论】:

以上是关于在Ruby中从末尾切片字符串的主要内容,如果未能解决你的问题,请参考以下文章

Shell脚本编程之字符串切片

列表/元组/切片/字典/字符串处理方法

shell字符串处理

Python学习之四集合类型

列表(索引与切片,增删改查) ,计数,排序,元祖和元祖的嵌套

字符串可以直接取值str[0],因为有切片方法