如何跨越多行拆分字符串并保留空行?

40

给定以下 Ruby 代码:

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

这将输出:
["aaaa", "bbbb"] 

我希望输出包括由\n\n指示的空行--我想要的结果是:
["aaaa", "bbbb", ""]

最简便/最优的方法是获得此精确结果是什么?
3个回答

59

我建议在这个任务中使用lines而不是splitlines将保留尾随的换行符,这样您就可以看到所需的空行。使用chomp进行清理:

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

其他更加复杂的方法包括:

"aaaa\nbbbb\n\n".split(/(\n)/).each_slice(2).map{ |ary| ary.join.chomp }
[
    [0] "aaaa",
    [1] "bbbb",
    [2] ""
]
它利用了在split中使用捕获组的优势,该组返回被拆分的文本及其间隔文本。each_slice然后将元素分组为两个元素的子数组。map获取每个两元素子数组,并执行join,然后是chomp。
或者说:
"aaaa\nbbbb\n\n".split(/(\n)/).delete_if{ |e| e == "\n" }
[
    [0] "aaaa",
    [1] "bbbb",
    [2] ""
]

这是 split 返回的内容:

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

我们不经常看到它被使用,但它可能很有用。


我喜欢这个答案。它让我觉得最清晰地捕捉到了我的意图。 - Kirk Woll
1
是的,我也喜欢这个更好,而且避免了split的数字参数的不良反应。 - Dave Newton
@shiva,你不能在MRI中对String使用map,因为它不是一个方法。也许你正在添加一些扩展String的东西? - the Tin Man
2
我已经是Ruby程序员六年了,但你刚刚教会了我lines方法。太棒了,谢谢! - Joshua Pinter

16

您可以为split方法的第二个参数提供负值以避免删除末尾的空字符串;

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

请注意,这将给您比您想要的多一个额外的空字符串。


哇,文档中的那个参数名并没有让它变得很明显。感谢你的指引! - Nathan Wallace

4

您可以使用数字参数,但我认为它有点棘手,因为(在我看来)它与我的预期不太一致,并且根据我所知,您需要修剪最后一个空字段:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接