2016-05-14 8 views
0

Ich möchte Parameter von URL extrahieren. Ich habe folgende Pfad Muster:Extrahieren Sie URL-Parameter in Ruby

pattern = "/foo/:foo_id/bar/:bar_id" 

Und Beispiel url:

url = "/foo/1/bar/2" 

Ich mag würde bekommen {foo_id: 1, bar_id: 2}. Ich habe versucht, Muster in etwas zu konvertieren:

"\/foo\/(?<foo_id>.*)\/bar\/(?<bar_id>.*)" 

ich auf den ersten Schritt schlug fehl, wenn ich Backslash in URL ersetzen wollte:

formatted = pattern.gsub("/", "\/") 

Wissen Sie, wie diese gsub zu beheben? Vielleicht weißt du eine bessere Lösung dafür.

EDIT: Es ist schlicht Ruby. Ich benutze keine RoR.

+0

Sie haben Backslash zu überspringen. probiere dies 'gsub ("/"," \\/")' –

+0

Du musst nur Schrägstriche in einem Regexp-Literal ('/ foo \/bar /') entschlüsseln. Wenn Sie einen Regexp aus einem String definieren, den Sie nicht benötigen ('Regexp.new (" foo/bar ")'). (Sie können dies selbst mit dem eingebauten 'Regexp.escape' überprüfen.' Regexp.escape ("foo/bar") 'gibt '" foo/bar "' zurück.) –

Antwort

1

Hash Wie ich oben sagte, müssen Sie nur Schrägstriche in einem Regexp wörtlichen, zum Beispiel zu entkommen /foo\/bar/. Wenn ein Regexp aus einem String definiert wird, ist es nicht notwendig: Regexp.new("foo/bar") erzeugt den gleichen Regexp wie /foo\/bar/.

In Bezug auf Ihr größeres Problem, hier ist, wie ich es lösen würde, was ich vermute, ich ziemlich viel, wie Sie es lösen würde geplant:

PATTERN_PART_MATCH = /:(\w+)/ 
PATTERN_PART_REPLACE = '(?<\1>.+?)' 

def pattern_to_regexp(pattern) 
    expr = Regexp.escape(pattern) # just in case 
      .gsub(PATTERN_PART_MATCH, PATTERN_PART_REPLACE) 
    Regexp.new(expr) 
end 

pattern = "/foo/:foo_id/bar/:bar_id" 
expr = pattern_to_regexp(pattern) 
# => /\/foo\/(?<foo_id>.+?)\/bar\/(?<bar_id>.+?)/ 

str = "/foo/1/bar/2" 
expr.match(str) 
# => #<MatchData "/foo/1/bar/2" foo_id:"1" bar_id:"2"> 
1

Versuchen Sie folgendes:

regex = /\/foo\/(?<foo_id>.*)\/bar\/(?<bar_id>.*)/i 
matches = "/foo/1/bar/2".match(regex) 
Hash[matches.names.zip(matches[1..-1])] 

IRB-Ausgang:

2.3.1 :032 > regex = /\/foo\/(?<foo_id>.*)\/bar\/(?<bar_id>.*)/i 
=> /\/foo\/(?<foo_id>.*)\/bar\/(?<bar_id>.*)/i 
2.3.1 :033 > matches = "/foo/1/bar/2".match(regex) 
=> #<MatchData "/foo/1/bar/2" foo_id:"1" bar_id:"2"> 
2.3.1 :034 > Hash[matches.names.zip(matches[1..-1])] 
=> {"foo_id"=>"1", "bar_id"=>"2"} 

ich diesen Artikel raten würde zu lesen, wie Rack-parst Abfrage params. Das obige funktioniert für dein Beispiel, das du angegeben hast, ist aber nicht erweiterbar für andere Params.

http://codefol.io/posts/How-Does-Rack-Parse-Query-Params-With-parse-nested-query

0

Dies könnte Ihnen helfen, wird die foo-ID und die Bar-ID dynamisch sein.

require 'json' 

#url to scan 
    url = "/foo/1/bar/2" 
#scanning ids from url 
    id = url.scan(/\d/) 
#gsub method to replacing values from url 
    url_with_id = url.gsub(url, "{foo_id: #{id[0]}, bar_id: #{id[1]}}") 

#output  
    => "{foo_id: 1, bar_id: 2}" 

Wenn Sie Zeichenfolge ändern möchten

url_hash = eval(url_with_id) 

=>{:foo_id=>1, :bar_id=>2} 
Verwandte Themen