2011-11-23 76 views
2

我想通過包含使用each_line方法的很多行的Ruby字符串循環,但我也想更改它們。我使用下面的代碼,但它似乎並沒有工作:替換ruby字符串中的行

string.each_line{|line| line=change_line(line)} 

我想,那紅寶石送我行的副本,而不是線本身,但可惜的是沒有方法each_line! 。我也試過用gsub!方法,使用/^.*$/來檢測每一行,但它似乎只調用change_line方法,並用它替換所有行。任何想法如何做到這一點? 在此先感謝:)

回答

3

您應該嘗試從空白字符串開始,each_lining通過字符串,然後將結果推送到空白字符串。

output = "" 
string.each_line{|line| output += change_line(line)} 

在您的原始示例中,您是正確的。你的變化正在發生,但它們並沒有在任何地方發生。 Ruby中的Each默認情況下不會更改任何內容。

+0

也可寫爲'輸出= string.lines.map {|線| change_line(線)} join'。 –

+0

'str + =「something」'會每次創建一個新的字符串。 http://stackoverflow.com/questions/5686621/ruby-string-concatenation-and – steenslag

1

你可以使用gsub!經過塊吧:

string.gsub!(/^(.*)$/) {|line| change_line(line)} 

來源:String#gsub!

1

String#each_line是指用於讀取一個串線,不寫他們。您可以使用它來得到你想要像這樣的結果:

changed_string = "" 
string.each_line{ |line| changed_string += change_line(line) } 
0

如果你不給each_line塊,你會得到一個枚舉,其中有注射方法。

str = <<HERE 
smestring dsfg 
line 2 
HERE 

res = str.each_line.inject(""){|m,line|m << line.upcase} 
4

@azlisum:你沒有存儲你的連接結果。使用:

output = string.lines.map{|line|change_line(line)}.join 

比較四種方式通過線中的字符串來處理:

# Inject method (proposed by @steenslang) 
output = string.each_line.inject(""){|s, line| s << change_line(line)} 

# Join method (proposed by @Lars Haugseth) 
output = string.lines.map{|line|change_line(line)}.join 

# REGEX method (proposed by @olistik) 
output = string.gsub!(/^(.*)$/) {|line| change_line(line)} 

# String concatenation += method (proposed by @Erik Hinton) 
output = "" 
string.each_line{|line| output += change_line(line)}     

與基準定時:

    user  system  total  real 
Inject Time: 7.920000 0.010000 7.930000 ( 7.920128) 
Join Time:  7.150000 0.010000 7.160000 ( 7.155957) 
REGEX Time: 11.660000 0.010000 11.670000 (11.661059) 
+= Time:  7.080000 0.010000 7.090000 ( 7.076423) 

正如@steenslag指出:「S + =一'將生成new string for each concatenation,因此通常不是最佳選擇。因此,考慮到

,並給予時間,最好的辦法是:

output = string.lines.map{|line|change_line(line)}.join 

此外,這是清潔期待的選擇恕我直言。

注:
Using Benchmark
Ruby-Doc: Benchmark

+0

非常感謝努力和解釋:) – mjekov