我需要允许路由匹配以下四种格式:
- 富
- foo.json
- foo.bar
- foo.bar.json
如果路由以“.json”结尾,则应该匹配之前的部分,因此这四个示例的唯一可能匹配项是“foo”和“foo.bar”。
我想出了以下正则表达式:/.*?(?=\.json|\Z)/
,但它不起作用,因为 Rails 不允许您\Z
在路由约束中使用:
路由要求中不允许使用正则表达式锚字符:
/.*?(?=\.json|\Z)/
有没有办法解决这个或其他我可以使用的正则表达式?
我需要允许路由匹配以下四种格式:
如果路由以“.json”结尾,则应该匹配之前的部分,因此这四个示例的唯一可能匹配项是“foo”和“foo.bar”。
我想出了以下正则表达式:/.*?(?=\.json|\Z)/
,但它不起作用,因为 Rails 不允许您\Z
在路由约束中使用:
路由要求中不允许使用正则表达式锚字符:
/.*?(?=\.json|\Z)/
有没有办法解决这个或其他我可以使用的正则表达式?
以下正则表达式将匹配整个字符串并仅捕获您需要的部分
(.*?)(?:\.json)?$
此正则表达式将匹配并仅捕获您需要的部分
^((?:.(?!\.json$))*(?:$|.))
http://rubular.com/r/SdtEDiWPRX
第二个正则表达式过于复杂,我非常怀疑您是否需要匹配和捕获完全相同。但是话又说回来,我对rails不太了解:)
您应该能够制作自己的定义 .matches 的对象?方法。结合@mrhobo 的正则表达式应该可以工作。
http://guides.rubyonrails.org/routing.html#advanced-constraints
我最终做的是创建两条不同的路由,一条带有 JSON,一条没有,都使用不同的正则表达式。所以以前的路线看起来像这样。
get ':foo', to: 'foo#bar', constraints: { foo: /.*?(?=\.json|\Z)/ }
现在看起来像这样:
get ':foo.json', to: 'foo#bar', constraints: { foo: /.*?(?=\.json)/ }, format: :json
get ':foo', to: 'foo#bar', constraints: { foo: /.*?/ }
您需要限制不是 url,而只能以这种方式格式化:
get 'foo', format: /bar|json|bar\.json/, to: 'main#foo'
格式将在控制器中提供为params[:format]
如果您想获得任意键,这并不是那么简单:
get ":foo(.:bar)", to: 'main#foo', bar: /(?!json$|html$)[^\.]*/
您应该关注的一件事是,:bar
不能json
(或任何其他适当的格式)
在您的控制器中,您将拥有params[:foo]
并且params[:bar]