2015-12-15 11 views
7

Ich versuche, durch Elemente einer Struktur zu durchlaufen, suchen Sie nach Zeichenfolgen, die das Format {...} enthalten, und ersetzen Sie sie durch eine entsprechende Zeichenfolge aus einem Hash. Dies sind die Daten Ich verwende:Verwenden von Regex zum Ersetzen von Parametern in einer Zeichenfolge

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

Dies ist Versuch 1:

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

In diesem Versuch, parameters["\1"] == nil.

Versuch 2:

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

Dies führt zu request.user == "first first". Trying parameters[match] Ergebnisse in nil.

Kann mir jemand helfen, dies zu lösen?

Antwort

5

Keines Ihrer Versuche funktioniert, weil die Argumente gsub! vor dem Aufruf von gsub! ausgewertet werden. parameters[...] wird vor dem Austausch ausgewertet, so dass es keine Möglichkeit gibt, die Übereinstimmung wiederzugeben. Außerdem wird "\1" nicht durch die erste Erfassung ersetzt, auch wenn diese Zeichenfolge das direkte Argument von gsub! war. Sie müssen die Escape-Zeichen wie "\\1“entkommen. Um es zu umgehen, müssen Sie einen Block zu gsub! geben.

Aber anstatt das zu tun, versuchen Sie, was bereits dort zu verwenden ist. Sie sollten %{} String-Format verwenden und verwenden Symbole für den Hash.

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

Hallo @sawa, Ihre Antwort ist groß, aber können Sie bitte die Magie hinter 'Wert% parameters' erklären. Ich habe nicht gesehen de den% Operator, der auf diese Weise zuvor verwendet wurde. – Scotty

+0

http://ruby-doc.org/core-2.2.0/String.html#method-i-25 – sawa

1

Sie gsub mit einem Block verwenden können.

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