2016-05-14 4 views
0

Я хотел бы извлечь параметры из url. У меня есть следующий шаблон пути:Извлечь url params в ruby ​​

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

И пример URL:

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

Я хотел бы получить {foo_id: 1, bar_id: 2}. Я попытался преобразовать рисунок в нечто вроде этого:

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

мне не удалось на первом этапе, когда я хотел заменить обратную косую черту в URL:

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

Вы знаете, как исправить эту GSUB? Возможно, вы знаете лучшее решение для этого.

EDIT: Это простой рубин. Я не использую RoR.

+0

Вы должны пропустить обратный слэш. попробуйте этот 'gsub ("/"," \\/")' –

+0

Вам нужно только вывести слэши в литерал Regexp ('/ foo \/bar /'). Если вы определяете Regexp из строки, вам не нужно ('Regexp.new (« foo/bar »)). (Вы можете проверить это самостоятельно, используя встроенный 'Regexp.escape'.' Regexp.escape ("foo/bar") 'возвращает' "foo/bar".). –

ответ

1

Как я уже говорил выше, вам нужно только, чтобы избежать косых черт в Regexp буквальных, например, /foo\/bar/. При определении Regexp из строки это необязательно: Regexp.new("foo/bar") создает такое же Regexp, как /foo\/bar/.

Что касается вашей большей проблемы, вот как я бы решить, что я предполагаю, что это довольно много, как вы планировали решить:

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

Попробуйте это:

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

IRB выход:

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"} 

Я советую читать эту статью о том, как Rack разбирает параметры запроса. Вышеупомянутое работает для вашего примера, который вы дали, но не расширяется для других параметров.

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

0

Это может помочь вам, то Foo идентификатор и идентификатор бар будет динамичным.

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}" 

Если вы хотите изменить строку в хэш

url_hash = eval(url_with_id) 

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