使用正则表达式替换字符串中的参数

时间:2015-12-15 03:02:18

标签: ruby regex

我正在尝试迭代结构的元素,查找包含格式{...}的字符串,并用散列中的相应字符串替换它们。这是我正在使用的数据:

Request = Struct.new(:method, :url, :user, :password)
request = Request.new
request.user = "{user} {name}"
request.password = "{password}"
parameters = {"user" => "first", "name" => "last", "password" => "secret"}

这是尝试1:

request.each do |value|
  value.gsub!(/{(.+?)}/, parameters["\1"])
end

在此次尝试中,parameters["\1"] == nil

尝试2:

request.each do |value|
  value.scan(/{(.+?)}/) do |match|
    value.gsub!(/{(.+?)}/, parameters[match[0]])
  end
end

这导致request.user == "first first"。尝试parameters[match]会产生nil

有人可以协助解决这个问题吗?

2 个答案:

答案 0 :(得分:5)

由于gsub!的参数在调用gsub!之前进行评估,因此您的尝试都无效。 parameters[...]将在替换前进行评估,因此无法反映匹配。此外,即使该字符串是"\1"的直接参数,gsub!也不会被第一次捕获所取代。你需要转义像"\\1"这样的转义字符。要使其有效,您需要为gsub!添加一个块。

但是,不要这样做,尝试使用现有的东西。您应该使用字符串格式%{}并使用符号作为哈希值。

request.user = "%{user} %{name}"
request.password = "%{password}"
parameters = {user: "first", name: "last", password: "secret"}
request.each do |value|
  value.replace(value % parameters)
end

答案 1 :(得分:1)

您可以将gsub与块一起使用。

request.each do |e|
  e.gsub!(/{.+?}/) { |m| parameters[m[1...-1]] } if e
end