I have a string containing many new line and spaces. I need to split it into fixed length sub strings. E.g
a = \"This is some\\nText\\nThis is some text\"
<
Yet another solution: unpack.
You need to construct a string for it like a17a17a17a17a8 (the last chunk needs to be shorter if the string is not exactly x times 17 chars long.
a = "This is some\nText\nThis is some text\nThis is some more text"
a.unpack(('a17' * (a.length / 17)) + (a.size % 17 == 0 ? "" : "a#{a.length - (a.length / 17) * 17}"))
=> ["This is some\nText", "\nThis is some tex", "t\nThis is some mo", "re text"]
This appears to be by far the fastest one of the suggested, of course if the input string is huge, the unpack string will be huge as well. If that is the case, you will want a buffered reader for that thing, read it in chunks of x * 17 and do something like the above for each chunk.
require 'benchmark'
a = "This is some\nText\nThis is some text" * 1000
n = 100
Benchmark.bm do |x|
x.report("slice ") { n.times do ; (0..(a.length / 17)).map{|i| a[i * 17,17] } ; end}
x.report("regex ") { n.times do ; a.scan(/.{1,17}/m) ; end}
x.report("eachc ") { n.times do ; a.each_char.each_slice(17).map(&:join) ; end }
x.report("unpack") { n.times do ; a.unpack(('a17' * (a.length / 17)) + (a.size % 17 == 0 ? "" : "a#{a.length - (a.length / 17) * 17}")) ; end }
end
Results:
user system total real
slice 0.120000 0.000000 0.120000 ( 0.130709)
regex 0.190000 0.000000 0.190000 ( 0.186407)
eachc 1.430000 0.000000 1.430000 ( 1.427662)
unpack 0.030000 0.000000 0.030000 ( 0.032807)