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

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

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

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

【问题讨论】:

    标签: ruby string split substring slice


    【解决方案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"]
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2017-07-07
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多