Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: [Bug] S-flag imposes non-greedy match where it shouldn't



I've updated the trick. It's now:

str="abcXXXdefXXXghi"
out=${(S)str%%(#b)([^X])X##(*)}
out=$out$match[1]$match[2]

The man page looks like http://psprint.blinkenshell.org/S_flag-2.png

I think that the trick is minimal to get the job done, i.e.: to
actually match a substring greedily starting from the right.

On Fri, 27 Dec 2019 at 05:54, Sebastian Gniazdowski
<sgniazdowski@xxxxxxxxx> wrote:
>
> The trick is not right. I'll try to update it or otherwise change the
> description.
>
> On Thu, 26 Dec 2019 at 19:35, Sebastian Gniazdowski
> <sgniazdowski@xxxxxxxxx> wrote:
> >
> > I've attached the extended description. It includes a trick to
> > work-around the unintuitive behavior of S. It looks as follows:
> >
> > http://psprint.blinkenshell.org/S_flag.png
> >
> > I think that the way the S flag works is a bit of an inconsistency,
> > Because ${str%%X##**} would not stop at the first from the right
> > match, it would try other matches starting from the right and go on up
> > to the final first from the left X. I think that (S) shouldn't change
> > this, but on the other hand should ${(S)str%%X##} match the first
> > three X? Rather not, as it would resemble ## then... Intuitively,
> > however, it should match all the three right X.
> >
> > On Thu, 19 Dec 2019 at 16:30, Daniel Shahaf <d.s@xxxxxxxxxxxxxxxxxx> wrote:
> > >
> > > Sebastian Gniazdowski wrote on Wed, 18 Dec 2019 20:44 +00:00:
> > > > Or rather not a bug… It seems that it's the result of how % searches
> > > > the substrings from the end – it stops at the first match, i.e.: after
> > > > finding a first X from the right.
> > >
> > > Could we improve the documentation of (S), then?
> >
> >
> >
> > --
> > Sebastian Gniazdowski
> > News: https://twitter.com/ZdharmaI
> > IRC: https://kiwiirc.com/client/chat.freenode.net:+6697/#zplugin
> > Blog: http://zdharma.org
>
>
>
> --
> Sebastian Gniazdowski
> News: https://twitter.com/ZdharmaI
> IRC: https://kiwiirc.com/client/chat.freenode.net:+6697/#zplugin
> Blog: http://zdharma.org



-- 
Sebastian Gniazdowski
News: https://twitter.com/ZdharmaI
IRC: https://kiwiirc.com/client/chat.freenode.net:+6697/#zplugin
Blog: http://zdharma.org
From 8176ef315181dc38e41e80c6509d591bddf86db1 Mon Sep 17 00:00:00 2001
From: Sebastian Gniazdowski <sgniazdowski@xxxxxxxxx>
Date: Thu, 26 Dec 2019 19:22:41 +0100
Subject: [PATCH] Extend description of S flag

---
 Doc/Zsh/expn.yo | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo
index d7147dbd7..36813dc20 100644
--- a/Doc/Zsh/expn.yo
+++ b/Doc/Zsh/expn.yo
@@ -1399,6 +1399,19 @@ from the beginning and with tt(%) start from the end of the string.
 With substitution via tt(${)...tt(/)...tt(}) or
 tt(${)...tt(//)...tt(}), specifies non-greedy matching, i.e. that the
 shortest instead of the longest match should be replaced.
+The substring search means that the pattern is matched skipping the
+parts of the input string starting from the direction set by the use
+of tt(#) or tt(%). For example, to match a pattern starting from the
+end, one could use:
+
+example(str="abcXXXdefXXXghi"
+out=${(S)str%%(#b)([^X])X##(*)}
+out=$out$match[1]$match[2])
+
+The result is tt(abcXXXdefghi). It would have been tt(abcXXXdefXXghi)
+if the substitution would have been tt(${(S)str%%X##}), as despite the
+tt(%%) specifies a greedy match, the substring matching works by
+trying matches from right to left and stops at a first valid match.
 )
 item(tt(I:)var(expr)tt(:))(
 Search the var(expr)th match (where var(expr) evaluates to a number).
-- 
2.21.0



Messages sorted by: Reverse Date, Date, Thread, Author