juxt / bidi

Bidirectional URI routing

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Regex extractors don't behave as expected

bjconlan opened this issue · comments

While attempting to resolve an issue regarding a typical url encoded path test/user%2B" I discovered that match-route function was returning nil.

(bidi/match-route ["/" {"test/" {[:slug] :om/details}}] "/test/user%2B")

Looking into the documentation/readme I discovered that there is a case to handle this issue which is simply to change the '[:slug] mapping handler to use a tuple of regex & keyword. In doing this I discovered that only the last character was being returned this can be exemplified by the following bidi function:

(bidi/match-route ["/" {"test/" {[#"[\w+\%]+" :slug] :om/details}}] "/test/user%2B")

Looking into the code I noticed that the function:

(bidi/match-pattern [#"[\w+\%]+" :slug] {:remainder "user%2B"})

Is building up a 'safe' regex which leads to unexpected results (in my case it became: #"([\w+\%]+)([A-Za-z0-9\-\_\.]+)(.*)) (line bidi.bidi.cljc#258)

Either I'm doing something that is entirely incorrect (usually the case) or the 'grouping' regex safety functionality is causing unexpected behavior (at least to what I've expected from the documentation)

Are there any updates on this? My regex is ignored and only ([A-Za-z0-9-_.]+)(.*)) is matched after being appended on bidi.bidi.cljc#258. I get only the last match (letter) unless I use an empty regex (#"")

Thanks for the tips, I ran into the same problem and Found a different solution:

["lesson" [[["" [#".*" :id]] #'lesson/lesson-view]]]

Note that instead of just [#".*" :id] I used ["" [#".*" :id]] and now it gives the full string.

The reason I needed the anything regex is because the route from that path can contain slashes.

I don't really grok why it has to be done this way... but putting the empty string before it seems to help.

This trick worked because bidi requires the #"regex" and :id to be in a vector pair within the overall vector.

For example:

(bidi/match-route ["/" {[#"\d+" :id] {"/" :id-handler}}] "/123/")

and

(bidi/match-route ["/" {[#"\d+" :id "/"] {"" :id-handler}}] "/123/")

will both fail whereas

(bidi/match-route ["/" {[[#"\d+" :id]] {"/" :id-handler}}] "/123/")

and

(bidi/match-route ["/" {[[#"\d+" :id] "/"] {"" :id-handler}}] "/123/")

will both succeed.

So for the original question this should work:

(bidi/match-route ["/" {"test/" {[[#"[\w+\%]+" :slug]] :om/details}}] "/test/user%2B")

Oh, I see, thank you for clarifying.