我试图从字符串执行内嵌红宝石。该字符串作为文本存储在数据库中,不是使用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