【问题标题】:How can I match /foo but not /foo/ in Perl's Catalyst?如何在 Perl 的 Catalyst 中匹配 /foo 而不是 /foo/?
【发布时间】:2010-09-14 23:14:03
【问题描述】:

我想匹配 /foo,但不匹配 /foo/(其中 foo 可以是任何字符串)或 /

我在这些方面尝试了很多东西:

sub match :Path :Regex('^[a-z]+$')
sub match :Regex('^[a-z]+$')
sub match :Path :Args(1)

但我无法达到我所需要的。

我不认为问题出在我的正则表达式上,而是因为我想处理没有参数的路径:

例如,对于 /aab/c,我从 Catalyst 获取:

[debug] "GET" request for "aab/c" from "192.168.1.100"
[debug] Path is "aab"
[debug] Arguments are "c"

【问题讨论】:

  • 您是否有机会提及为什么您想这样做?我想不出一个。
  • 是的,我越想越觉得这个功能被故意省略了。

标签: regex perl catalyst


【解决方案1】:

No :Args 指定将意味着“任意数量的参数,0 或更大”。这意味着在您的初始示例中,/foo/bar/foo/bar/baz 是匹配的。正则表达式本身不匹配的正则表达式之后的路径元素将作为动作的参数被吃掉。

(那些告诉您有关您的正则表达式并说“我不知道 Catalyst 但是”的人在这里忽略了一点,即正则表达式匹配器中的 $ 可以在“/”之前匹配,而不是总是在末尾URL 的一部分,在 Catalyst 中。然后将其余部分用作参数。)

您将需要 :Args(0) 来实现您想要实现的目标,并指定将 0 路径部分用作参数(因此 /foo/bar 匹配)。

但是,使用

进行快速测试
sub match :LocalRegex('^[a-z]+$') :Args(0)

证明/foo/foo/ 都匹配,(但这更接近一步:/match/xyz 不匹配)。 Catalyst 在路径中特别处理“/”,所以我不确定你是否可以做得比这更好。

【讨论】:

    【解决方案2】:

    根据the docs

    正则表达式匹配行为全局,即不参考调用它的命名空间...

    如果您希望正则表达式仅匹配当前命名空间的根,请尝试改用 LocalRegex 操作:

    sub match : LocalRegex('^[a-z]+$')
    

    【讨论】:

      【解决方案3】:

      Regex 或 LocalRegex 只有在没有其他更具体的操作可以处理请求时才会匹配。

      您需要支持sub lowermatch :Regex ('/([a-z]+)/([a-z]+)') { } 才能捕获/foo/bar 并适当地处理它。不过,您现有的存根不应该捕获“/”。那应该通过 Root->default

      如果没有参数,您也可以 $c->forward 在现有的 sub 中,即:

      sub match :Regex ('/foo') {
          my ($self, $c, @args) = @_;
          $c->forward('noargs_action') unless @args;
          ...
      }
      

      希望对您有所帮助。

      【讨论】:

        【解决方案4】:

        免责声明:我不熟悉 Catalyst;这些是 (Perl) 正则表达式。

        如果“foo”必须是字母数字,这将满足您的需求:

        ^\/\w*$
        

        如果“foo”真的可以是任何东西,请改用它:

        ^\/$|^\/.*[^\/]$
        

        【讨论】:

          【解决方案5】:

          LocalRegex 操作可能适合您所描述的内容,但如果您正在做这种事情,那么您就是在与 HTTP 规范作斗争。

          【讨论】:

            【解决方案6】:

            我不知道 Catalyst,但根据阅读文档,它看起来像你想要的

            子匹配:Regex('^[a-zA-Z]*$') {}

            正则表达式分解如下:

            • ^ 匹配就在根之后(即 /)
            • [a-zA-Z]* 匹配零个或多个 a-z 或 A-Z 字符
            • $匹配url结尾

            【讨论】:

            • 这几乎是用一种奇怪的方式编写的正则表达式:-)
            【解决方案7】:

            这个答案可能不是您想要的,但为了完整起见,我只是想把它放在这里:我可能会使用 ModRewrite 之类的东西来进行从 /foo/ 到 /foo 变体的重定向。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-06-12
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2015-07-30
              • 1970-01-01
              相关资源
              最近更新 更多