2015-07-18 86 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