基于 Regexp 的路径匹配

匹配路径的路径时,你可以显式地执行此操作,仅匹配一个路径,如下所示:

get "/hello" do
    return "Hello!"
end

你还可以使用正则表达式来匹配复杂路径。与正则表达式匹配的任何路由都将运行该代码块。如果多个路由可能与请求匹配,则执行第一个匹配的路由。

以下是匹配路径的典型示例,其中包含/user/后跟一个或多个数字(可能是用户 ID),即 GET /user/1

get /\/user\/\d+/ do
  "Hello, user!"
end

上面的示例匹配/user/1,但也匹配/delete/user/1/user/1/delete/now,因为我们的正则表达式不是非常严格,并且允许与路径的任何部分进行部分匹配。

我们可以更加明确地使用正则表达式并告诉它与路线完全匹配,使用\A\z 指令将匹配锚定到路径的开头和结尾:

get /\A\/user\/\d+\z/ do
  "Hello, user!"
end

由于匹配锚定,此路线将不匹配/delete/user/1/user/1/delete/now

忽略尾随/

我们上面的示例路由也不匹配/user/1/(尾随正斜杠)。如果要忽略路径末尾的尾部斜杠,请调整正则表达式以使斜杠可选( 请注意末尾的\/? ):

get /\A\/user\/\d+\/?\z/ do
  "Hello, user! You may have navigated to /user/<ID> or /user/<ID>/ to get here."
end

捕获路线匹配

到目前为止,我们已经匹配了 regexp 路由,但是如果我们想在代码块中使用匹配的值呢?按照我们的示例,我们如何知道执行路由时用户的 ID 是什么?

我们可以捕获路径的所需部分,并使用 Sinatra 的 param[:captures] 变量来处理路径中的数据:

get /\A\/user\/(\d+)\/?\z/ do
  "Hello, user! Your ID is #{params['captures'].first}!"
end