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

Re: How do I find shortest match?



On Thu, 17 May 2012 15:11:09 -0400
TJ Luoma <luomat@xxxxxxxxx> wrote:
> > local min
> > min=(${${(o)${MATCHES//?/\?}}[1]})
> > print -l ${MATCHES:#^${~min}}
> > 
> > I'm sure it's completely obvious what this is doing. It's been
> posted before.
> I have the memory and attention span of a tsetse fly, so I'll take
> your word for it,

I think it was some years ago now.

> although I myself have no idea what this is doing.

(I should have pointed out it needs EXTENDED_GLOB for the "^".)

First it replaces all the characters in all the elements of $MATCHES
with a question mark, then orders them in the standard collating order
with (o).  As all the characters are the same, the shortest string comes
first and [1] picks it.  So $min is a single element array containing as
many ?'s as there characters in the shortest string.

The next match "simply" eliminates from MATCHES (':#') anything that
doesn't match ('^') the pattern ${~min}, where the ~ turns the ?'s into
active pattern characters.  So this matches any element of MATCHES which
has as many characters as the shortest string.  In fact, that could be
more than one, so you really need

${${MATCHES:#^${~min}}[1]}

to select the first.

-- 
Peter Stephenson <p.w.stephenson@xxxxxxxxxxxx>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/



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