1

我想匹配 /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"
4

7 回答 7

2

仅当没有其他更具体的操作可以处理请求时,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;
    ...
}

希望有帮助。

于 2009-04-26T06:28:27.367 回答
2

According to the docs,

Regex matches act globally, i.e. without reference to the namespace from which it is called...

If you want the regex to match only at the root of the current namespace, try using a LocalRegex action instead:

sub match : LocalRegex('^[a-z]+$')
于 2009-04-26T02:56:53.130 回答
2

否 :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 特别在路径中处理'/',所以我不确定你是否能做得比这更好。

于 2009-04-28T12:49:23.080 回答
1

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

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

^\/\w*$

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

^\/$|^\/.*[^\/]$
于 2009-04-25T22:51:14.033 回答
1

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

于 2009-04-26T06:30:34.070 回答
0

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

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

正则表达式分解如下:

  • ^ 在根之后匹配(即 /)
  • [a-zA-Z]* 匹配零个或多个 az 或 AZ 字符
  • $ 匹配 url 的结尾
于 2009-04-25T22:50:16.750 回答
0

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

于 2010-09-14T15:14:03.007 回答