簡體   English   中英

如何從Ruby中的String獲取第一行?

[英]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: ' ')

不要把中間的單詞剪掉,當在你選擇的字符數之后找到一個空格時它會結束。

API文檔

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM