Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: Substitute the last match of a pattern during parameters expansion.
On Sun, Sep 11, 2022 at 11:01 PM Lawrence Velázquez <larryv@xxxxxxx> 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@xxxxxxx> 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]}}
Messages sorted by:
Reverse Date,
Date,
Thread,
Author