![](/img/trans.png)
[英]How to get the data from line number n to last line from a multi-line string in ruby?
[英]How to get first line from String in Ruby?
我在 Ruby 中有一个字符串变量,如下所示:
puts $varString.class
puts "##########"
puts $varString
上面代码的输出是:
String
##########
my::FIrst::Line
this id second line
sjdf kjsdfh jsdf
djsf sdk fxdj
我只需要从字符串变量中获取第一行(例如my::FIrst::Line
)。 我怎么才能得到它?
# Ruby >= 1.8.7
$varString.lines.first
# => "my::FIrst::Line"
# Ruby < 1.8.7
$varString.split("\n").first
# => "my::FIrst::Line"
作为旁注,避免使用全局( $
符号)变量。
$varString.lines.first
或者,如果您想在结果字符串中去掉最后的换行符:
$varString.lines.first.chomp
str = <<DOC1
asrg
aeg
aegfr
DOC1
puts str[0..(str.index("\n")|| -1)]
避免读取数组中的整个字符串。 (如果字符串中没有行结尾, ||-1 可以避免错误)。 编辑str.lines 不会创建数组。
first_line = str[/.*/]
该解决方案似乎是内存分配和性能方面最有效的解决方案。
这使用str[regexp]
形式,请参阅https://ruby-doc.org/core-2.6.5/String.html#method-i-5B-5D
基准代码:
require 'stringio'
require 'benchmark/ips'
require 'benchmark/memory'
str = "test\n" * 100
Benchmark.ips do |x|
x.report('regex') { str[/.*/] }
x.report('index') { str[0..(str.index("\n") || -1)] }
x.report('stringio') { StringIO.open(str, &:readline) }
x.report('each_line') { str.each_line.first.chomp }
x.report('lines') { str.lines.first }
x.report('split') { str.split("\n").first }
x.compare!
end
Benchmark.memory do |x|
x.report('regex') { str[/.*/] }
x.report('index') { str[0..(str.index("\n") || -1)] }
x.report('stringio') { StringIO.open(str, &:readline) }
x.report('each_line') { str.each_line.first.chomp }
x.report('lines') { str.lines.first }
x.report('split') { str.split("\n").first }
x.compare!
end
基准测试结果:
Comparison:
regex: 5099725.8 i/s
index: 4968096.7 i/s - 1.03x slower
stringio: 3001260.8 i/s - 1.70x slower
each_line: 2330869.5 i/s - 2.19x slower
lines: 187918.5 i/s - 27.14x slower
split: 182865.6 i/s - 27.89x slower
Comparison:
regex: 40 allocated
index: 120 allocated - 3.00x more
stringio: 120 allocated - 3.00x more
each_line: 208 allocated - 5.20x more
lines: 5064 allocated - 126.60x more
split: 5104 allocated - 127.60x more
@steenslag 答案的替代方法是使用 StringIO 仅获取第一行。
str = <<DOC1
asrg
aeg
aegfr
DOC1
puts StringIO.open(str, &:readline)
如果字符串很大,这可以避免将字符串拆分成一个大数组并只读取第一行。 请注意,如果字符串为空,则会引发 EOFError。
puts $varString.split('\n')[0]
在 '\\n' 标记上拆分字符串,并获得第一个
您也可以使用 truncate 方法。
'Once upon a time in a world far far away'.truncate(27, separator: ' ')
# => "Once upon a time in a..."
.truncate(200number of characters, separator: ' ')
不要把中间的单词剪掉,当在你选择的字符数之后找到一个空格时它会结束。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.