Kirk Woll
Kirk Woll

Reputation: 77536

How to split string across new lines and keep blank lines?

Given the ruby code:

"aaaa\nbbbb\n\n".split(/\n/)

This outputs:

["aaaa", "bbbb"] 

I would like the output to include the blank line indicated by \n\n -- I want the result to be:

["aaaa", "bbbb", ""]

What is the easiest/best way to get this exact result?

Upvotes: 40

Views: 39619

Answers (3)

the Tin Man
the Tin Man

Reputation: 160551

I'd recommend using lines instead of split for this task. lines will retain the trailing line-break, which allows you to see the desired empty-line. Use chomp to clean up:

"aaaa\nbbbb\n\n".lines.map(&:chomp)
[
    [0] "aaaa",
    [1] "bbbb",
    [2] ""
]

Other, more convoluted, ways of getting there are:

"aaaa\nbbbb\n\n".split(/(\n)/).each_slice(2).map{ |ary| ary.join.chomp }
[
    [0] "aaaa",
    [1] "bbbb",
    [2] ""
]

It's taking advantage of using a capture-group in split, which returns the split text with the intervening text being split upon. each_slice then groups the elements into two-element sub-arrays. map gets each two-element sub-array, does the join followed by the chomp.

Or:

"aaaa\nbbbb\n\n".split(/(\n)/).delete_if{ |e| e == "\n" }
[
    [0] "aaaa",
    [1] "bbbb",
    [2] ""
]

Here's what split is returning:

"aaaa\nbbbb\n\n".split(/(\n)/)
[
    [0] "aaaa",
    [1] "\n",
    [2] "bbbb",
    [3] "\n",
    [4] "",
    [5] "\n"
]

We don't see that used very often, but it can be useful.

Upvotes: 59

Dave Newton
Dave Newton

Reputation: 160170

You can use the numeric argument, but IMO it's a bit tricky since (IMO) it's not quite consistent with what I'd expect, and AFAICT you'd want to trim the last null field:

jruby-1.6.7 :020 > "aaaa\nbbbb\n\n".split(/\n/, -1)[0..-2]
 => ["aaaa", "bbbb", ""] 

Upvotes: 4

Mark Byers
Mark Byers

Reputation: 837946

You can supply a negative argument for the second parameter of split to avoid stripping trailing empty strings;

"aaaa\nbbbb\n\n".split(/\n/, -1)

Note that this will give you one extra empty string compared to what you want.

Upvotes: 16

Related Questions