拆分字符串抑制所有空字段

时间:2010-09-23 00:03:25

标签: ruby split

我想拆分一个字符串来抑制所有空字段

命令:

",1,2,,3,4,,".split(',')

结果:

["", "1", "2", "", "3", "4", ""]

预期:

["1", "2", "3", "4"]

怎么做?


修改

确定。只是总结一下所有好的问题。

我想要的是split方法(或其他方法)没有生成空字符串。看起来不可能。

所以,解决方案是两步过程:像往常一样拆分字符串,然后以某种方式从结果数组中删除空字符串。

第二部分正是this question (及其duplicate

所以我会用

",1,2,,3,4,,".split(',').delete_if(&:empty?) 

Nikita Rybak和user229426提出的解决方案是使用拒绝方法。根据{{​​3}},拒绝返回一个新数组。虽然docs方法更有效,因为我不想要副本。使用Mark Byers提出的delete_if效率更低。

steenslag建议用空格替换逗号,然后按空格分割:

",1,2,,3,4,,".gsub(',', ' ').split(' ')

实际上,select说空间实际上是一个空白区域。但是“split(/ \ s /)”和“split('')”的结果并不相同。为什么?

Mark Byers提出了另一种解决方案 - 只使用正则表达式。似乎这就是我需要的。但是这个解决方案意味着你必须成为regexp的主人。但这是很好的解决方案!例如,如果我需要空格作为分隔符以及任何非字母数字符号,我可以将其重写为

",1,2, ,3 3,4 4 4,,".scan(/\w+[\s*\w*]*/)

结果是:

["1", "2", "3 3", "4 4 4"]

但是再次使用regexp是非常不直观的,他们需要一种经验。

摘要

我希望分割能够用空格来表达,就好像空格是逗号甚至正则表达式一样。我希望它不会产生空字符串。我认为这是红宝石中的一个错误或我的误解。

将其作为社区问题。

5 个答案:

答案 0 :(得分:14)

Array中有一个reject方法:

",1,2,,3,4,,".split(',').reject { |s| s.empty? }

或者如果您更喜欢Symbol#to_proc

",1,2,,3,4,,".split(',').reject(&:empty?)

答案 1 :(得分:3)

希望在这里说明一点:

  

但是“split(/ \ s /)”和“split('')”的结果并不相同。为什么?

如果你查看String#split的文档,你会看到用''拆分是一个特例:

If pattern is a single space, str is split on whitespace,
with leading whitespace and runs of contiguous whitespace characters ignored.

你还提到:

  

我希望它不会产生空字符串。我认为这是红宝石中的一个错误或我的误解。

问题可能出在键盘和椅子之间。 ; - )

split会愉快地生成空字符串,因为有时你肯定会想要这种能力,并且有很多简单的方法可以解决它。考虑是否从Excel文件中拆分csv。你看到的任何地方',,'都是一个空列,而不是你应该摆脱的专栏。

无论如何,你已经看到了一堆解决方案 - 这是另一个可以向你展示你可以用红宝石和拆分做的事情的解决方案!

您似乎想要在多个逗号之间拆分数据,那么为什么不试试看看会发生什么?

a = ",1,2,,3,4,,5,,,,6,,,".split(/,+/)

这是一个足够简单的正则表达式:/,+ /表示一个或多个逗号,所以我们将拆分它。

除了您还想忽略前导空字段外,这几乎可以让您想要。您会注意到split会忽略末尾的空字段,因为(来自String#split docs):

If the limit parameter is omitted, trailing null fields are suppressed.

这意味着我们可以使用能够在数组前面删除nil的东西,或者只删除最初的逗号。我们可以使用gsub:

a = ",1,2,,3,4,,5,,,,6,,,".gsub(/^,+/,'')

如果你打印出来,你会看到我们的尾随空“字段”现在消失了。所以我们可以将它们组合在一行中:

a = ",1,2,,3,4,,5,,,,6,,,".gsub(/^,+/,'').split(/,+/)

你有另一个解决方案!

顺便提一下,这指出了另一种可能性,即如果我们想要一个简单的拆分,我们可以在将它发送到拆分之前完全清理我们的字符串。我会留给你弄清楚这个人在做什么:

a = ",1,2,,3,4,,5,,,,6,,,".gsub(/,+/,',').gsub(/^,/,'').split(',')

在ruby中有很多方法可以做。如果看起来ruby没有按照你想要的那样做,那么看看文档并意识到它可能会以某种方式起作用(有很多人如果分裂不能就会感到不安)吐出空场:)

希望有所帮助!

答案 2 :(得分:1)

您可以使用split后跟select

",1,2,,3,4,,".split(',').select{|x|!x.empty?}

或者您可以使用正则表达式来匹配您想要保留的内容,而不是在分隔符上拆分:

",1,2,,3,4,,".scan(/[^,]+/)

答案 3 :(得分:0)

",1,2,,3,4,,".split(/,/).reject(&:empty?)

",1,2,,3,,,4,,".squeeze(",").sub(/^,*|,*$/,"").split(",")

答案 4 :(得分:0)

当pattern是单个空格(ruby-doc)时,String#split(pattern)的行为符合要求。

",1,2,,3,4,,".gsub(',', ' ').split(' ')