在红宝石中提取url params

时间:2016-05-14 11:36:15

标签: ruby url params

我想从网址中提取参数。我有以下路径模式:

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

示例网址:

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

我想得到{foo_id:1,bar_id:2}。我试图将模式转换成这样的东西:

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

当我想在url中替换反斜杠时,第一步失败了:

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

你知道如何修复这个gsub吗?也许你知道更好的解决方案。

编辑: 这是纯粹的Ruby。我没有使用RoR。

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

正如我上面所说,你只需要在Regexp文字中转义斜杠,例如: /foo\/bar/。从字符串定义Regexp时,没有必要:Regexp.new("foo/bar")生成与/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">

答案 2 :(得分:0)

这可能会对您有所帮助,foo id和bar id将是动态的。

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}