On Wed, Sep 14, 2022, 01:11 Bart Schaefer <schaefer@brasslantern.com> wrote:
On Sun, Sep 11, 2022 at 11:01 PM Lawrence Velázquez <larryv@zsh.org> wrote:
>
>         % foo=aXbXcXdXe
>         % print ${(*)foo/(#b)(*)X/$match[1]Y}

That works for the last match, but not for the Nth-from-last.  (It
also works only in zsh 5.9+, before that you need extendedglob set.)

You can do it more generally like this:

N=0  # Number of X to skip over when counting from the right
print -- ${(*)foo/%(#b)(*)X(*(X*)(#c$N))/$match[1]Y$match[2]}

Nested parens with #b and #c are a bit iffy though, e.g., the values
of $match[3] and beyond here are not what you might expect.

On Mon, Sep 12, 2022 at 11:07 PM Lawrence Velázquez <larryv@zsh.org> wrote:
>
> Your use case could theoretically be satisfied by an enhanced 'I'
> flag, so I don't think it deserves its own flag.
>
> On Tue, Sep 13, 2022, at 12:19 AM, Michele Venturi wrote:
> > How do you extend the I flag?
>
> I don't know.  I am not familiar with the code base.

Unfortunately this is non-trivial, because the value of the parameter
is scanned+replaced left-to-right and we don't know how many matches
there will be, to count backward.

If you want to simulate a negative 'I' flag, one way is to use an
array, splitting and joining on the substring to replace:

N=-2
foo=aXbXcXdXe
z=(${(s:X:)foo})
print -- ${(j:X:)z[1,N-1]}Y${(j:X:)z[N,-1]}

Which you can write as a single substitution if you want to obfuscate it:

print -- ${${(A)z::=${(@s:X:)foo}}:+${(j:X:)z[1,N-1]}Y${(j:X:)z[N,-1]}}


Thanks for supporting my idea, even if unconsciously,
that explains why we need a dedicated flag very well...

Plus you seem quite good at non trivial tasks if you can
write that monstrousity... Do you know instead what IS trivial? Counting, to know how many matches there are.

There are many examples of supporting negative index,
so I still don't see a reason why it is so difficult to do it...