
Me deparei com um script zsh que contém esta expansão de parâmetro
${LBUFFER%%(#m)[_a-zA-Z0-9]#}
Para quem quiser conhecer o contexto em que esta expressão vive, ela faz parte de umfunção de widget zle que fornece abreviações semelhantes ao vim
Sua forma básica é obviamente um sufixo trim. ou seja${name%%pattern}
ou seja, de man zshexpn
- EXPANSÃO DE PARÂMETROS
${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; [...]
A respeito desinalizador de expansão de parâmetro (#m)
: deman 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.
em relação à [_a-zA-Z0-9]#
parte, este é obviamente o padrão que é removido do final da LBUFFER
string, mas este é um padrão regex ou algum híbrido globbing de regex?
Faz parte dos padrões "extended_glob" específicos do zsh?, ou seja, deman zshoptions
EXTENDED_GLOB Treat the `#', `~' and `^' characters as part of patterns for filename generation, etc. (An initial unquoted `~' always pro‐ duces named directory expansion.)
o que essa expansão de parâmetro zsh faz?
Responder1
Parece que é uma expressão zsh "glob estendido".
ou seja, deman zshexpn
Sinalizadores Globbing
Existem vários sinalizadores que afetam qualquer texto à sua direita até o final do grupo envolvente ou até o final do padrão; eles exigem a opção EXTENDED_GLOB. Todos assumem a forma (#X), onde X pode ter uma das seguintes formas:[...]
m
Definir referências aos dados de correspondência para toda a string correspondida; isso é semelhante à referência retroativa e não funciona na geração de nomes de arquivos. A bandeira deve estar em vigor no final do padrão, ou seja, não local para um grupo. Os parâmetros $MATCH, $MBEGIN e $MEND serão definidos para a string correspondida e para os índices de início e fim da string, respectivamente. Isto é mais útil em substituições de parâmetros, caso contrário a string correspondente é óbvia.Por exemplo,
arr=(veldt jynx grimps waqf zho buck) print ${arr//(#m)[aeiou]/${(U)MATCH}}
força todas as correspondências (ou seja, todas as vogais) para letras maiúsculas, imprimindo `vEldt jynx grImps wAqf zhO bUck'. Ao contrário das referências anteriores, não há penalidade de velocidade para o uso de referências de correspondência, além das substituições extras necessárias para as strings de substituição em casos como o exemplo mostrado.
e o #
operador é chamado de "fechamento" ou operador de correspondência repetida, equivalente a *
em regex
como explicado aquihttp://zsh.sourceforge.net/Guide/zshguide05.html#l139
então basicamente, esta expansão de parâmetro:
${LBUFFER%%(#m)[_a-zA-Z0-9]#}
iniciará uma referência anterior no estilo regex começando (#m)
onde qualquer padrão correspondente estará disponível em uma variável $MATCH
como \1
em um BRE ou $1
em um PCRE.
E porque #
é igual *
, [_a-zA-Z0-9]#
corresponderá a zero ou muitos caracteres do conjunto de caracteres [_a-zA-Z0-9]
.