Search code examples
regexperlcatalyst

How can I match /foo but not /foo/ in Perl's Catalyst?


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]+$')
sub match :Regex('^[a-z]+$')
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:

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

Solution

  • 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]+$') :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.