如何在 Perl 的 Catalyst 中匹配 /foo 而不是 /foo/?

发布于 2024-07-17 13:35:13 字数 413 浏览 4 评论 0原文

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

I want to match /foo, but not /foo/ (where foo can be any string) or /

I tried a lot of things along these lines:

sub match :Path :Regex('^[a-z]+

But I cannot achieve what I need.

I don't believe the problem is with my regex, but because I want to handle a path without an argument:

For example, for /aab/c, I get from Catalyst:

[debug] "GET" request for "aab/c" from "192.168.1.100"
[debug] Path is "aab"
[debug] Arguments are "c"
) sub match :Regex('^[a-z]+

But I cannot achieve what I need.

I don't believe the problem is with my regex, but because I want to handle a path without an argument:

For example, for /aab/c, I get from Catalyst:


)
sub match :Path :Args(1)

But I cannot achieve what I need.

I don't believe the problem is with my regex, but because I want to handle a path without an argument:

For example, for /aab/c, I get from Catalyst:

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

绮烟 2024-07-24 13:35:13

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

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

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

然而,快速测试

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

表明 /foo/foo/ 都匹配,(但这更近了一步:/match/xyz没有)。 Catalyst 在路径中特别对待“/”,所以我不确定您是否可以做得更好。

) :Args(0)

表明 /foo/foo/ 都匹配,(但这更近了一步:/match/xyz没有)。 Catalyst 在路径中特别对待“/”,所以我不确定您是否可以做得更好。

No :Args specified will mean 'any number of arguments, 0 or greater'. This means that in your initial examples, /foo/bar and /foo/bar/baz are matches. Path elements after the regex that the regex itself doesn't match will get eaten as arguments to the action.

(People who are telling you things about your regexp and saying 'I don't know Catalyst but' are missing the point here that $ in a regexp matcher can match just before a '/', and not always at the end of the URL, in Catalyst. The rest is then used as arguments.)

You will require :Args(0) for what you're trying to achieve, specifying that 0 path parts are to be used as arguments (so /foo/bar doesn't match).

However, a quick test using

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

demonstrates that /foo and /foo/ both match, (but this is a step closer: /match/xyz doesn't). Catalyst treats '/' specially in paths, so I'm not sure if you can do better than this.

) :Args(0)

demonstrates that /foo and /foo/ both match, (but this is a step closer: /match/xyz doesn't). Catalyst treats '/' specially in paths, so I'm not sure if you can do better than this.

潜移默化 2024-07-24 13:35:13

根据 文档,

正则表达式匹配全局作用,即不引用调用它的名称空间...

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

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

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]+
)
2024-07-24 13:35:13

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

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

或者,如果没有参数,您可以在现有子中 $c->forward,即:

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

希望有帮助。

Regex or LocalRegex will only match if there is no other more specific action that could handle the request.

You need to support sub lowermatch :Regex ('/([a-z]+)/([a-z]+)') { } to catch /foo/bar and handle it appropriately. Your existing stub shouldn't be catching '/' though. That should be going through to Root->default

Alternatively you can $c->forward in your existing sub if there are no arguments, ie:

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

Hope that helps.

无远思近则忧 2024-07-24 13:35:13

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

如果“foo”必须是字母数字,这将执行您想要的操作:

^\/\w*$

如果“foo”确实可以是任何内容,请改用它:

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

Disclaimer: I'm not familiar with Catalyst; these are (Perl) regexes.

If "foo" must be alphanumeric this will do what you want:

^\/\w*$

If "foo" can truly be anything, use this instead:

^\/$|^\/.*[^\/]$
人事已非 2024-07-24 13:35:13

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

LocalRegex actions are probably OK for what you describe, but you're fighting against the HTTP spec if you're doing this kind of thing.

倒数 2024-07-24 13:35:13

我不知道 Catalyst,但根据阅读文档,您似乎想要

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

正则表达式如下所示:

  • ^ 匹配在root (即 /)
  • [a-zA-Z]* 匹配零个或多个 az 或 AZ 字符
  • $ 匹配 url 的结尾

I don't know Catalyst, but based on reading the docs it looks like you want

sub match :Regex('^[a-zA-Z]*$') {}

The regex breaks down like this:

  • ^ match just after the root (i.e. the /)
  • [a-zA-Z]* matches zero or more a-z or A-Z characters
  • $ match the end of the url
一笔一画续写前缘 2024-07-24 13:35:13

这个答案可能不是您正在寻找的,但我只是想把它放在这里是为了完整性:我可能会使用像 ModRewrite 这样的东西来从 /foo/ 重定向到 /foo 变体。

This answer might not be what you're looking for, but I just want to put it in here for completeness sake: I would probably use something like ModRewrite to make a redirect from the /foo/ to the /foo variant.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文