我試圖從字符串執行內嵌紅寶石。該字符串作爲文本存儲在數據庫中,不是使用ruby製作的。從字符串執行內嵌紅寶石
string = 'The year now is #{Time.now.year}'
puts string
返回
=> The year now is #{Time.now.year}
我想它返回
=> The year now is 2015
是否有紅寶石的任何方法,將執行這樣的內聯紅寶石?
我試圖從字符串執行內嵌紅寶石。該字符串作爲文本存儲在數據庫中,不是使用ruby製作的。從字符串執行內嵌紅寶石
string = 'The year now is #{Time.now.year}'
puts string
返回
=> The year now is #{Time.now.year}
我想它返回
=> The year now is 2015
是否有紅寶石的任何方法,將執行這樣的內聯紅寶石?
我結束了一個方法,它會找到內聯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
是的,你的不工作的唯一原因是因爲單引號導致字符串文字(意味着沒有轉義或嵌入)。
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。
您可以使用eval
做到這一點,但警告說,在數據庫中以代碼串治療是非常危險的:
eval('puts "the sum of 2 and 2 is #{2+2}"')
如何在這樣的eval中使用字符串變量? eval('puts「#{string}」')會給我原來的結果 –
@lassvi不可能。顯示你的嘗試。 –
如果答案沒有足夠清楚:**確保您可以信任所有傳入的字符串,因爲它們可以包含將被執行的任意代碼**。你不希望你的用戶擦除/修改應用程序的某些部分,不是嗎? :] –
對於字符串插值工作,你必須使用雙引號..一個字符串字面量用單引號創建不支持插值。
string = "The year now is #{Time.now.year}"
您可以使用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#%
方法檢查。
即使它不是內聯ruby的一部分,它會從文本中刪除所有「}」:/(但它對於這個例子來說工作得很好我有我的問題,但數據庫將包含更多和不同的文本) –
是的,但你沒有問或帶出。但是,刪除該代碼可能是暫時的,但對於評估,您始終可以顯示原始數據。這也不是一個很好的正則表達式。我只能回答這個問題,希望不要在提出這些問題時做出錯誤的假設。 :) – vgoff
你可以看看ERB做到這一點,但需要適當地改變'#{'部分。你也將從ERB獲得安全。 – vgoff