Ruby:拆分,然后原地删除前导/尾随空格?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17641348/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Ruby: Split, then remove leading/trailing whitespace in place?
提问by Ben
things = "one thing, two things, three things, four things"
Given this input, how do I split a string by a comma and then trim the whitespace around it in place? Resulting in:
给定这个输入,我如何用逗号分割一个字符串,然后在适当的位置修剪它周围的空格?导致:
things = ["one thing", "two things", "three things", "four things"]
Currently I have this:
目前我有这个:
things = things.to_s.tr("\n\t", "").strip.split(/,/)
This does most of what I want it to do, except removing the leading/trailing whitespace when it splits on the comma. What's the best way to achieve this? I'd like to do it as part of this expression, instead of assigning the above result to a separate array and iterating over that.
这完成了我想要它做的大部分事情,除了在逗号分隔时删除前导/尾随空格。实现这一目标的最佳方法是什么?我想把它作为这个表达式的一部分,而不是将上面的结果分配给一个单独的数组并对其进行迭代。
回答by Arup Rakshit
s = "one thing, two things, three things, four things"
s.split(",").map(&:strip)
# => ["one thing", "two things", "three things", "four things"]
In my Ubuntu 13.04OS,using Ruby 2.0.0p0
在我的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)
回答by Koraktor
Use a regular expression for #split:
使用正则表达式#split:
"one thing, two things, three things, four things".split /\s*,\s*/
# => ["one thing", "two things", "three things", "four things"]
回答by Jon Kern
As a speed junkie, I love benchmarks... But let's face it, unless you are doing this operation inside of a million loops in your code, the speed differences are probably not going to impact your code nearly as much as having obvious coding constructs.
作为一个速度迷,我喜欢基准测试……但是让我们面对现实吧,除非您在代码中的一百万个循环中执行此操作,否则速度差异可能不会像具有明显的编码结构那样影响您的代码.
In my opinion, if performance doesn't matter, @arup has the best, most straightforward, clearest solution.
在我看来,如果性能不重要,@arup 有最好、最直接、最清晰的解决方案。
回答by xentek
Not to beat a dead horse, but you can speed this up a bit more by making two changes that have become second nature to me now. The first is use map!instead of mapto avoid creating a copy of the split array, and the second is to avoid use of the symbol to proc syntax (e.g. &:split, which adds an extra operation that can be avoided with the more verbose syntax).
不要打败一匹死马,但你可以通过做出两个现在已经成为我第二天性的改变来加快速度。第一个是使用map!而不是map避免创建拆分数组的副本,第二个是避免使用符号 to proc 语法(例如&:split,它添加了一个额外的操作,可以使用更详细的语法来避免)。
Benchmark follows:
基准如下:
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
Results:
结果:
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)
Remember to read the numbers relative to each other, not relative to the benchmarks provided in other answers.
请记住阅读彼此相关的数字,而不是与其他答案中提供的基准相关的数字。
回答by pjs
This is not meant as an answer to the original question, but I wanted to share benchmark code to let people check the two proposed solutions for themselves:
这并不是对原始问题的回答,但我想分享基准代码,让人们自己检查两个提议的解决方案:
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
On my system (Ruby 2.0.0p247 on OS X 10.8) that produced the following output:
在我的系统(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)
These results can, of course, be expected to vary between ruby versions, hardware, and OS's.
当然,这些结果可能会因 ruby 版本、硬件和操作系统而异。
回答by meschi
If i'm not mistaken
如果我没错的话
things.split(", ")
would be the easiest solution. However, it only works when there is exactly one space character. (Notice the space after the comma)
将是最简单的解决方案。但是,它仅在只有一个空格字符时才有效。(注意逗号后面的空格)

