I like to do non-greedy globs, but my Google searches hint that this is not supported. Is this the case? If so, why is it the case?

For example I'd like to use a non-greedy glob in history expansions, e.g. ^ff* ^open to open an mp3 previously ffplayed.


Zsh doesn't have non-greedy wildcards. The only place I can think of where it does non-greedy matching is when stripping a prefix with the parameter substitution forms ${VAR#PATTERN} and ${VAR%PATTERN} (as opposed to ${VAR##PATTERN} and ${VAR%%PATTERN} which match greedily).

It's always possible to translate a pattern using non-greedy wildcards into one that doesn't use them, but the translation can be painful and the size of the result is exponential in the size of the original in the worst case. A classic example of when non-greedy matching would be convenient is when you want to match a numeric range followed by something else with e.g. <1-42>*: this matches 43a because <1-42> matches 4; a workaround is <1-42>([^0-9]*)#. Depending on what you want to do, other methods may be easier, for example arranging to use a prefix or suffix substitution, or approaching the problem from a different angle.

For the use case of a history expansion where you want to change the command, there's a different approach which is one character shorter as your example and is more reliable in your specific example. Instead of ^ff* ^open which matches ff anywhere on the command line and only works if the argument doesn't contain a space, you can use

open !ff:*

which only matches ff at the beginning of the command line (!?ff would match anywhere).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.