comby-tools/comby

Ability to drop/modify suffix?

jacobbednarz opened this issue · 5 comments

I've got a matcher that I'm using to rewrite parts of URLs to be consistent - playground

This is working 99% of the way there however, for :[topic] in the replacement, I'd like to drop the trailing "s" suffix if it exists.

Current: /foos/{bar}/quaxs/{baz} becomes /foos/{foos_identifier}/quaxs/{quaxs_identifier}
Desired: /foos/{bar}/quaxs/{baz} becomes /foos/{foo_identifier}/quaxs/{quax_identifier}

Are there any pointers or ideas on how I could achieve this within comby?

Hi @jacobbednarz! I would do it with a rewrite rule.

You can add this to the command line invocation with

-rule 'where rewrite :[topic] { :[x]s -> :[x] }'

Basically, this rule fires and rewrites topic if :[x]s matches and leaves it untouched otherwise.

Docs for this: https://comby.dev/docs/advanced-usage#rewrite-expressions

I thought about and tried regex with lookahead (comby supports perl regex in that syntax) and things like boundary assertions (but those don't seem to pan out and probably misleading / tricky behavior to reason about)

ah thank you! I didn't even click that a rule could be applicable here. appreciate it!

sorry for reusing this issue but i've got some behaviour here that i'm not sure about - https://bit.ly/3vGPy9f.

my expectation is that /zones/{foo}/rulesets/phases/{bar}/entrypoint/versions/{baz} becomes /zones/{zone_id}/rulesets/phases/{phase_id}/entrypoint/versions/{version_id} however, for some reason, the "s" in the middle of these words is being targeted. am i holding this wrong? or is there a different syntax i should be using here instead?

hey @jacobbednarz, good question, it seems I simplified this in my head too early 😄

I'll give a workaround before the longer explanation. It is a bit trickier to grok but I think it works in the general case:

https://bit.ly/47G5PbN

Basically, we make the / of the path part of the match, and then we can use that context to chop off an s before / (and not just any s, which is what was happening before). Note the changes to the rule and the output pattern.

Strictly speaking you only need to match the trailing / so this also works:

https://bit.ly/48HAua6

Long explanation,

What was happening before is that, the way comby matches something like :[x]s is "match as much as possible until you see the thing after it (in this case s)". So when it matches against phases, it matches up to pha, sees an s after it, and stops. so we end up with two :[x]s -> :[x] happening twice for phases -> [pha][e]. But what we really want is only the last s. How do we know what is "last"? It turns out it's difficult to use regex or comby to say what is "last", and we don't have a "chop suffix" function or something like that yet. But based on your pattern, we know that a / means the s before it is "last", so we are using that fact to chop the suffix. Hope that helps

ah, that makes perfect sense! thanks again 🥇