如何(轻松)在Ruby中拆分字符串的长度和分隔符

Fer*_*eak 3 ruby string split

我需要在Ruby中拆分一个字符串,其格式如下:

 [{a:1,b:2,c:3,d:4},{a:5,b:6,c:7,d:8},{a:9,b:10,c:11,d:12},{a:13,b:14,c:15,d:16}]
Run Code Online (Sandbox Code Playgroud)

即.它是一个生成的javascript数组.不幸的是,列表很长,我希望在达到适合使用代码编辑器编辑它的特定长度之后将其拆分为数组元素分隔符逗号,但是要保持元素的完整性.例如,上面的分割宽度为15的行将变为:

 [{a:1,b:2,c:3,d:4},
 {a:5,b:6,c:7,d:8},
 {a:9,b:10,c:11,d:12},
 {a:13,b:14,c:15,d:16}]
Run Code Online (Sandbox Code Playgroud)

并且宽度为32的文本将是:

 [{a:1,b:2,c:3,d:4},{a:5,b:6,c:7,d:8},
 {a:9,b:10,c:11,d:12},{a:13,b:14,c:15,d:16}]
Run Code Online (Sandbox Code Playgroud)

除了经典的"强力"方法(循环,检查分隔符之间} 和{增加长度,如果长度大于和发现有效分隔符,则拆分)是否有更"红宝石"的问题解决方案?

编辑:附加天真的方法,绝对不是Rubyiish,因为我没有非常强大的Ruby背景:

def split(what, length)
  result = []
  clength = 0
  flag = FALSE
  what_copy = what.to_s
  what_copy.to_s.each_char do |c|
     clength += 1
     if clength > length
       flag = TRUE
     end

     if  c == '}' and flag
        result << what[0 .. clength]
        what = what[clength+1 .. -1]
        clength = 0
       flag = FALSE
     end
  end
  pp result
  sres = result.join("\n")
  sres
end
Run Code Online (Sandbox Code Playgroud)

Eri*_*nil 6

您可以使用正则表达式:

  • 至少是width-2字符的非贪婪重复
  • 接下来是 }
  • 然后是a ,或a ].

data = "[{a:1,b:2,c:3,d:4},{a:5,b:6,c:7,d:8},{a:9,b:10,c:11,d:12},{a:13,b:14,c:15,d:16}]"

def split_data_with_min_width(text, width)
  pattern = /
    (                 # capturing group for split
      .{#{width-2},}? # at least width-2 characters, but not more than needed
      \}              # closing curly brace
      [,\]]           # a comma or a closing bracket
    )
    /x                # free spacing mode
  text.split(pattern).reject(&:empty?).join("\n")
end

puts split_data_with_min_width(data, 15)
# [{a:1,b:2,c:3,d:4},
# {a:5,b:6,c:7,d:8},
# {a:9,b:10,c:11,d:12},
# {a:13,b:14,c:15,d:16},
# {a:17,b:18,c:19,d:20}]

puts split_data_with_min_width(data, 32)
# [{a:1,b:2,c:3,d:4},{a:5,b:6,c:7,d:8},
# {a:9,b:10,c:11,d:12},{a:13,b:14,c:15,d:16},
# {a:17,b:18,c:19,d:20}]
Run Code Online (Sandbox Code Playgroud)

该方法使用split捕获组而不是scan因为字符串的最后部分可能不够长:

"abcde".scan(/../)
# ["ab", "cd"]
"abcde".split(/(..)/).reject(&:empty?)
# ["ab", "cd", "e"]
Run Code Online (Sandbox Code Playgroud)