尝试在我的一个Rails模型中添加一个非常基本的描述模板。我想要做的是采用这样的模板字符串:
template = "{{ name }} is the best {{ occupation }} in {{ city }}."
和这样的哈希:
vals = {:name => "Joe Smith", :occupation => "birthday clown", :city => "Las Vegas"}
并获取生成的描述。我想我可以用一个简单的gsub做到这一点,但Ruby 1.8.7不接受哈希作为第二个参数。当我像这样的块做gsub时:
> template.gsub(/\{\{\s*(\w+)\s*\}\}/) {|m| vals[m]}
=> " is the best in ."
你可以看到它用整个字符串(带花括号)替换它,而不是匹配捕获。
如何用vals [“something”](或vals [“something”.to_sym])取代“{{something}}”?
TIA
答案 0 :(得分:24)
string formatting operator %
会将带有哈希值的字符串格式化为 arg
>> template = "%{name} is the best %{occupation} in %{city}."
>> vals = {:name => "Joe Smith", :occupation => "birthday clown", :city => "Las Vegas"}
>> template % vals
=> "Joe Smith is the best birthday clown in Las Vegas."
The string formatting operator in Ruby 1.8.7 doesn't support hashes。相反,您可以使用与Ruby 1.9.2解决方案相同的参数并修补String对象,因此在升级Ruby时,您不必编辑字符串。
if RUBY_VERSION < '1.9.2'
class String
old_format = instance_method(:%)
define_method(:%) do |arg|
if arg.is_a?(Hash)
self.gsub(/%\{(.*?)\}/) { arg[$1.to_sym] }
else
old_format.bind(self).call(arg)
end
end
end
end
>> "%05d" % 123
=> "00123"
>> "%-5s: %08x" % [ "ID", 123 ]
=> "ID : 0000007b"
>> template = "%{name} is the best %{occupation} in %{city}."
>> vals = {:name => "Joe Smith", :occupation => "birthday clown", :city => "Las Vegas"}
>> template % vals
=> "Joe Smith is the best birthday clown in Las Vegas."
答案 1 :(得分:2)
最容易的事情可能是在你的区块中使用$1.to_sym
:
>> template.gsub(/\{\{\s*(\w+)\s*\}\}/) { vals[$1.to_sym] }
=> "Joe Smith is the best birthday clown in Las Vegas."
来自fine manual:
在块形式中,当前匹配字符串作为参数传入,并且将适当地设置诸如$ 1,$ 2,$`,$&amp;和$'的变量。块返回的值将替换每次调用的匹配。