2015-07-18 36 views
0

我試圖從字符串執行內嵌紅寶石。該字符串作爲文本存儲在數據庫中,不是使用ruby製作的。從字符串執行內嵌紅寶石

string = 'The year now is #{Time.now.year}' 
puts string 

返回

=> The year now is #{Time.now.year} 

我想它返回

=> The year now is 2015 

是否有紅寶石的任何方法,將執行這樣的內聯紅寶石?

+0

你可以看看ERB做到這一點,但需要適當地改變'#{'部分。你也將從ERB獲得安全。 – vgoff

回答

0

我結束了一個方法,它會找到內聯ruby,並在每個ruby部件上使用eval()方法。

def text(text) 
    text.scan(/\#{.*?}/).each do |a| 
     text = text.gsub(a,eval(a[2..-2]).to_s) 
    end 
    text 
end 
string = 'The year now is #{Time.now.year}' 
puts text(string) 
=> The year now is 2015 

編輯:

d方想出了一個更好的解決方案:

puts eval %Q("#{string}") 
=> The year now is 2015 
6

是的,你的不工作的唯一原因是因爲單引號導致字符串文字(意味着沒有轉義或嵌入)。

string = "The year now is #{Time.now.year}" 
puts string 

會工作(注意雙引號)。

編輯1:

另一種解決方案(除了其他的eval),是使用串內插。

string = 'Time is: %s' 
puts string % [Time.now.year] 

所以,你可以用%s替代:

string = 'The year now is %s' 
=> "The year now is %s" 
2.2.1 :012 > string % [Time.now.year] 
=> "The year now is 2015" 

更多here

+0

正如我所說的,字符串是從數據庫中加載的,並不是用ruby製作的,上面只是一個例子。我無法更改原始字符串變量。 –

+0

我會更新一秒。 – wkcamp

+0

如果數據庫還包含單引號,則必須使用正則表達式並將其替換。以String#gsub爲例。 – three

1

您可以使用eval做到這一點,但警告說,在數據庫中以代碼串治療是非常危險的:

eval('puts "the sum of 2 and 2 is #{2+2}"') 
+0

如何在這樣的eval中使用字符串變量? eval('puts「#{string}」')會給我原來的結果 –

+0

@lassvi不可能。顯示你的嘗試。 –

+0

如果答案沒有足夠清楚:**確保您可以信任所有傳入的字符串,因爲它們可以包含將被執行的任意代碼**。你不希望你的用戶擦除/修改應用程序的某些部分,不是嗎? :] –

1

對於字符串插值工作,你必須使用雙引號..一個字符串字面量用單引號創建不支持插值。

string = "The year now is #{Time.now.year}" 
0

您可以使用ERB這一點。

require 'erb' 

from_database = 'The time is now #{Time.new.year}' 

new_string = from_database.sub(/\#\{/, '<%= ') 
new_string = new_string.sub(/\}/, '%>') 
puts ERB.new(new_string).run 

沒有檢查用於驗證它是串內插,也不能用於使用String#%方法檢查。

+0

即使它不是內聯ruby的一部分,它會從文本中刪除所有「}」:/(但它對於這個例子來說工作得很好我有我的問題,但數據庫將包含更多和不同的文本) –

+0

是的,但你沒有問或帶出。但是,刪除該代碼可能是暫時的,但對於評估,您始終可以顯示原始數據。這也不是一個很好的正則表達式。我只能回答這個問題,希望不要在提出這些問題時做出錯誤的假設。 :) – vgoff