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

时间:2017-04-20 11:23:47

标签: 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}]

即。它是一个生成的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}]

,宽度为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}]

除了经典的“蛮力”方法(循环,检查}{之间的分隔符,同时增加长度,如果长度大于和找到有效分隔符则拆分)是否有更多“Rubyish “问题的解决方案?

编辑:附加天真的方法,绝对不是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

3 个答案:

答案 0 :(得分:6)

您可以使用正则表达式:

  • 非贪婪重复至少width-2个字符
  • 后跟}
  • 后跟,]
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}]

该方法使用split代替scan,因为字符串的最后部分可能不够长:

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

答案 1 :(得分:2)

<强>代码

def doit(str, min_size)   
  r = /
      (?:                # begin non-capture group                
        .{#{min_size},}? # match at least min_size characters, non-greedily
        (?=\{)           # match '{' in a positive lookahead
        |                # or
        .+\z             # match one or more characters followed by end of string
      )                  # close non-capture group
      /x                 # free-spacing regex definition mode
  str.scan(r)
end

<强>实施例

str = "[{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}]"

doit(str, 18) # same for all min_size <= 18
  #=> ["[{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}]"] 
doit(str, 19)
  #=> ["[{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}]"]
doit(str, 20)
  #=> ["[{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}]"] 
doit(str, 21)
  #=> ["[{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}]"] 
doit(str, 22) # same for 23 <= min_size <= 37
  #=> ["[{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}]"]
doit(str, 38) # same for 39 <= min_size <= 58
  #=> ["[{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}]"] 
doit(str, 59) # same for min_size > 59
  #=> ["[{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}]"] 

答案 2 :(得分:1)

喜欢这个吗?

2.3.1 :007 > a
 => "[{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}]" 
2.3.1 :008 > q =  a.gsub("},", "},\n")
 => "[{a:1,b:2,c:3,d:4},\n{a:5,b:6,c:7,d:8},\n{a:9,b:10,c:11,d:12},\n{a:13,b:14,c:15,d:16}]" 
2.3.1 :009 > puts q
[{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}]
 => nil 
2.3.1 :010 >