我已经加载了一个带有 #{variable} 引用的字符串。我将如何解决字符串中的这些变量puts
呢?
name="jim"
str="Hi #{name}"
puts str
我希望将结果作为参数传递或保存到变量中,而不是放置。
我已经加载了一个带有 #{variable} 引用的字符串。我将如何解决字符串中的这些变量puts
呢?
name="jim"
str="Hi #{name}"
puts str
我希望将结果作为参数传递或保存到变量中,而不是放置。
puts
不解决变量。Ruby 解析器在创建字符串时执行此操作。如果您传递str
给任何其他方法,则与传递“Hi jim”相同,因为插值已经完成。
你可以评估它
name = "Patrick"
s = 'hello, #{name}'
s # => "hello, \#{name}"
# wrap the string in double quotes, making it a valid interpolatable ruby string
eval "\"#{s}\"" # => "hello, Patrick"
String 有一个格式选项,显示为%
. 它可用于将参数传递到预定义的字符串中,就像插值一样。
message = "Hello, %s"
for_patrick = message % "Patrick" #=> "Hello, Patrick"
for_jessie = message % "Jessie" #=> "Hello, Jessie"
messages = "Hello, %s and %s"
for_p_and_j = messages % ["Patrick", "Jessie"] #=> "Hello, Patrick and Jessie"
它可能看起来不像“Rubyish”,但我相信它是您正在寻找的功能。
因此,如果您有一个来自某个地方的字符串包含这些占位符,那么您可以将值作为参数传递,如下所示:
method_that_gets_hello_message % "Patrick"
这也将允许您只接受您期望的值。
message = "I can count to %d"
message % "eleven" #=> ArgumentError: invalid value for Integer()
维基百科上有一个可能的占位符列表printf()
,它也应该在 Ruby 中工作。
听起来您需要模板系统的基础,如果您使用字符串gsub
或sub
方法,Ruby 很容易做到这一点。
replacements = { '%greeting%' => 'Hello', '%name%' => 'Jim' }
pattern = Regexp.union(replacements.keys)
'%greeting% %name%!'.gsub(pattern, replacements)
=> "Hello Jim!"
您可以轻松地将密钥定义为:
replacements = { '#{name}' => 'Jim' }
并使用 Ruby 的普通字符串插值#{...}
,但我建议不要重用它。而是使用独特的东西。
这样做的好处是目标 => 替换映射可以很容易地放入 YAML 文件或数据库表中,然后您可以将它们换成其他语言或不同的用户信息。天空才是极限。
这样做的好处也是,不涉及评估,它只是字符串替换。通过一些创造性的使用,您实际上可以实现宏:
macros = { '%salutation%' => '%greeting% %name%' }
replacements = { '%greeting%' => 'Hello', '%name%' => 'Jim' }
macro_pattern, replacement_pattern = [macros, replacements].map{ |h| Regexp.union(h.keys) }
'%salutation%!'.gsub(macro_pattern, macros).gsub(replacement_pattern, replacements)
=> "Hello Jim!"
这eval
似乎是这个特定任务的唯一解决方案。但是如果我们稍微修改一下任务,我们可以避免这种肮脏的不安全的耻辱 :我们可以不使用eval
本地变量而是实例变量:eval
instance_variable_get
@name = "Patrick"
@id = 2 # Test that number is ok
@a_b = "oooo" # Test that our regex can eat underscores
s = 'hello, #{name} !!#{id} ??#{a_b}'
s.gsub(/#\{(\w+)\}/) { instance_variable_get '@'+$1 }
=> "hello, Patrick !!2 ??oooo"
在这种情况下,您甚至可以使用任何其他字符来代替#{}
(例如%name%
等),只需稍微修改一下正则表达式。
但是,当然,这一切都闻起来了。