
Ich bin auf ein ZSH-Skript gestoßen, das diese Parametererweiterung enthält
${LBUFFER%%(#m)[_a-zA-Z0-9]#}
Für alle, die wissen möchten, in welchem Kontext dieser Ausdruck steht: Er ist Teil einerzle-Widget-Funktion, die vim-ähnliche Abkürzungen bereitstellt
Seine Grundform ist offensichtlich ein Suffix trim. ie${name%%pattern}
dh von man zshexpn
- PARAMETER-ERWEITERUNG
${name%pattern} ${name%%pattern} If the pattern matches the end of the value of name, then sub‐ stitute the value of name with the matched portion deleted; [...]
bezüglich derParametererweiterungsflag (#m)
: ausman zshexpn
# Evaluate the resulting words as numeric expressions and output the characters corresponding to the resulting integer. Note that this form is entirely distinct from use of the # without parentheses. m Only useful together with one of the flags l or r or with the # length operator when the MULTIBYTE option is in effect. Use the character width reported by the system in calculating how much of the string it occupies or the overall length of the string. Most printable characters have a width of one unit, however cer‐ tain Asian character sets and certain special effects use wider characters; combining characters have zero width. Non-printable characters are arbitrarily counted as zero width; how they would actually be displayed will vary.
in Bezug auf den [_a-zA-Z0-9]#
Teil ist dies offensichtlich das Muster, das vom Ende der LBUFFER
Zeichenfolge entfernt wird, aber ist dies ein Regex-Muster oder ein Regex-Glob-Hybrid?
Ist es Teil der zsh-spezifischen „extended_glob“-Muster?, also vonman zshoptions
EXTENDED_GLOB Treat the `#', `~' and `^' characters as part of patterns for filename generation, etc. (An initial unquoted `~' always pro‐ duces named directory expansion.)
was macht diese Zsh-Parametererweiterung?
Antwort1
Es scheint, dass es sich dabei um einen zsh-„Erweiterter Glob“-Ausdruck handelt.
d.h. vonman zshexpn
Globbing-Flags
Es gibt verschiedene Flags, die jeden Text rechts von ihnen bis zum Ende der umschließenden Gruppe oder des Musters beeinflussen; sie erfordern die Option EXTENDED_GLOB. Alle haben die Form (#X), wobei X eine der folgenden Formen haben kann:[...]
m
Setzen Sie Referenzen auf die Übereinstimmungsdaten für die gesamte übereinstimmende Zeichenfolge; dies ähnelt der Rückreferenzierung und funktioniert nicht bei der Generierung von Dateinamen. Das Flag muss am Ende des Musters wirksam sein, also nicht lokal für eine Gruppe. Die Parameter $MATCH, $MBEGIN und $MEND werden auf die übereinstimmende Zeichenfolge bzw. auf die Indizes des Anfangs und Endes der Zeichenfolge gesetzt. Dies ist besonders bei Parameterersetzungen nützlich, da die übereinstimmende Zeichenfolge sonst offensichtlich ist.Zum Beispiel,
arr=(veldt jynx grimps waqf zho buck) print ${arr//(#m)[aeiou]/${(U)MATCH}}
zwingt alle Übereinstimmungen (also alle Vokale) in Großbuchstaben und gibt `vEldt jynx grImps wAqf zhO bUck' aus. Anders als bei Rückverweisen gibt es bei der Verwendung von Übereinstimmungsverweisen keine Geschwindigkeitseinbußen, abgesehen von den zusätzlichen Ersetzungen, die für die Ersatzzeichenfolgen in Fällen wie dem gezeigten Beispiel erforderlich sind.
und der #
Operator ist ein sogenannter „Closure“- oder Repeated-Match-Operator, äquivalent zu *
Regex
wie hier erklärthttp://zsh.sourceforge.net/Guide/zshguide05.html#l139
also im Wesentlichen diese Parametererweiterung:
${LBUFFER%%(#m)[_a-zA-Z0-9]#}
startet eine Rückreferenz im Regex-Stil, beginnend bei , (#m)
wo jedes übereinstimmende Muster in einer Variablen verfügbar sein wird, $MATCH
wie \1
in einem BRE oder $1
in einem PCRE.
Und weil #
es genauso ist wie *
, [_a-zA-Z0-9]#
wird es mit null oder vielen Zeichen aus dem Zeichensatz übereinstimmen [_a-zA-Z0-9]
.