使用RegExp的Sinatra路由参数

时间:2012-09-14 04:06:14

标签: ruby regex sinatra

我正在尝试创建一个小的sinatra示例,该示例将打印一个月,日或年的日历视图,具体取决于URL。这样

localhost:4567 / calendar / 2012将打印年视图日历

localhost:4567 / calendar / 2012/9将打印一个月日历

localhost:4567 / calendar / 2012/9/15将打印日视图日历

我的工作原理如下:

require 'sinatra'

get '/calendar/:year/:month/:day/?' do
    "printing daily calendar for #{params[:year]}/#{params[:month]}/#{params[:day]}"
end

get '/calendar/:year/:month/?' do
    "printing monthly calendar for #{params[:year]}/#{params[:month]}"
end

get '/calendar/:year/?' do
    "printing yearly calendar for #{params[:year]}"
end

我的问题是,我是否可以使用某种RegEx进一步优化这些路由,以便我可以说如果:月份部分介于1和12之间并且:day部分介于1和31之间,则仅计算url吗

2 个答案:

答案 0 :(得分:7)

如果您使用的是ruby 1.9+,则可以使用这样的命名捕获:

get %r{/(?<year>\d{4})/(?<month>\d{2})/(?<day>\d{2})/?} do
 "printing daily calendar for #{params[:year]}/#{params[:month]}/#{params[:day]}"
end

get %r{/(?<year>\d{4})/(?<month>\d{2})/?} do
  "printing monthly calendar for #{params[:year]}/#{params[:month]}"
end

get %r{/(?<year>\d{4})/?} do
  "printing monthly calendar for #{params[:year]}"
end

答案 1 :(得分:2)

是。您可以在sinatra路由条件中指定正则表达式。有关详细信息,请参阅sinatra readme

get %r{/calendar/([\d]+)/(1[0-2]|0?[1-9])/([12][0-9]|3[0-1]|0?[1-9])$} do 
  "hello #{params[:captures]}"
end

get %r{/calendar/([\d]+)/(1[0-2]|0?[1-9])$} do 
  "hello #{params[:captures]}"        
end

# host/2012/11 will print "hello [2012, 11]"
# params[:captures] will return an array containing what match the regular expressions