Como funciona essa expansão do parâmetro zsh?

Como funciona essa expansão do parâmetro zsh?

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 LBUFFERstring, 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 $MATCHcomo \1em um BRE ou $1em um PCRE.
E porque #é igual *, [_a-zA-Z0-9]#corresponderá a zero ou muitos caracteres do conjunto de caracteres [_a-zA-Z0-9].

informação relacionada