Ruby:拆分,然后删除前导/尾随空格?

时间:2013-07-14 16:37:13

标签: ruby

things = "one thing, two things, three things, four things"

根据这个输入,我如何用逗号分割字符串然后修剪它周围的空白?导致:

things = ["one thing", "two things", "three things", "four things"]

目前我有这个:

things = things.to_s.tr("\n\t", "").strip.split(/,/)

除了在逗号上拆分时删除前导/尾随空格,这除了我想要它做的大部分工作。实现这一目标的最佳方法是什么?我想把它作为这个表达式的一部分,而不是将上面的结果分配给一个单独的数组并迭代它。

6 个答案:

答案 0 :(得分:71)

s = "one thing, two things, three things, four things"
s.split(",").map(&:strip)
# => ["one thing", "two things", "three things", "four things"]

在我的 Ubuntu 13.04 操作系统中,使用 Ruby 2.0.0p0

require 'benchmark'

s = "one thing, two things, three things, four things"
result = ""

Benchmark.bmbm do |b|
  b.report("strip/split: ") { 1_000_000.times {result = s.split(",").map(&:strip)} }
  b.report("regex: ") { 1_000_000.times {result = s.split(/\s*,\s*/)} }
end

Rehearsal -------------------------------------------------
strip/split:    6.260000   0.000000   6.260000 (  6.276583)
regex:          7.310000   0.000000   7.310000 (  7.320001)
--------------------------------------- total: 13.570000sec

                    user     system      total        real
strip/split:    6.350000   0.000000   6.350000 (  6.363127)
regex:          7.290000   0.000000   7.290000 (  7.302163)

答案 1 :(得分:7)

使用#split的正则表达式:

"one thing, two things, three things, four things".split /\s*,\s*/
# => ["one thing", "two things", "three things", "four things"]

答案 2 :(得分:6)

作为一个速度迷,我喜欢基准测试...但是让我们面对它,除非你在代码中的一百万个循环中进行这个操作,速度差异可能不会影响你的代码几乎和明显的编码结构。

在我看来,如果性能无关紧要,@ arup拥有最好,最直接,最清晰的解决方案。

答案 3 :(得分:3)

不要击败死马,但是你可以通过做出两个对我来说已成为第二天性的改变来加快速度。第一个是使用map!而不是map来避免创建split数组的副本,第二个是避免使用符号来处理proc语法(例如&:split,这会添加一个使用更详细的语法可以避免额外的操作。

基准如下:

require 'benchmark'

s = "one thing, two things, three things, four things"
result = ""

Benchmark.bmbm do |b|
    b.report("strip/split (map/to_proc): ") { 1_000_000.times { result = s.split(",").map(&:strip) } }
    b.report("strip/split (map): ") { 1_000_000.times { result = s.split(",").map { |e| e.strip } } }
    b.report("strip/split (map!/to_proc): ") { 1_000_000.times { result = s.split(",").map!(&:strip) } }
    b.report("strip/split (map!): ") { 1_000_000.times { result = s.split(",").map! { |e| e.strip } } }
    b.report("regex: ") { 1_000_000.times { result = s.split(/\s*,\s*/) } }
end

结果:

                                   user     system      total        real
strip/split (map/to_proc):     5.230000   0.010000   5.240000 (  5.283079)
strip/split (map):             4.660000   0.010000   4.670000 (  4.716920)
strip/split (map!/to_proc):    4.440000   0.020000   4.460000 (  4.492943)
strip/split (map!):            4.320000   0.010000   4.330000 (  4.365386)
regex:                         7.190000   0.060000   7.250000 (  7.322932)

请记住阅读相对于彼此的数字,而不是相对于其他答案中提供的基准。

答案 4 :(得分:2)

这并不是对原始问题的回答,但我想分享基准代码,让人们自己检查两个建议的解决方案:

require 'benchmark'

s = "one thing, two things, three things, four things"
result = ""

Benchmark.bmbm do |b|
  b.report("strip/split: ") { 1_000_000.times {result = s.split(",").map(&:strip)} }
  b.report("regex: ") { 1_000_000.times {result = s.split(/\s*,\s*/)} }
end

在我的系统(OS X 10.8上的Ruby 2.0.0p247)上产生以下输出:

Rehearsal -------------------------------------------------
strip/split:    2.140000   0.000000   2.140000 (  2.143905)
regex:          3.570000   0.010000   3.580000 (  3.572911)
---------------------------------------- total: 5.720000sec

                    user     system      total        real
strip/split:    2.150000   0.000000   2.150000 (  2.146948)
regex:          3.580000   0.010000   3.590000 (  3.590646)

当然,这些结果可能会在ruby版本,硬件和操作系统之间有所不同。

答案 5 :(得分:2)

如果我没弄错的话

things.split(", ")

将是最简单的解决方案。但是,它只适用于只有一个空格字符的情况。 (注意逗号后面的空格)