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

1

Me deparei com um script zsh que contém essa expansão de parâmetro

${LBUFFER%%(#m)[_a-zA-Z0-9]#}

Para qualquer pessoa que queira conhecer o contexto em que esta expressão vive, ela faz parte de uma função de widget zle que fornece o vim como abreviações

Sua forma básica é obviamente um ajuste de sufixo. ou seja, ${name%%pattern}

i.e. 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;
     [...]

sobre o sinalizador de expansão de parâmetro (#m) : de man 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 à parte [_a-zA-Z0-9]# , este é obviamente o padrão que é removido do final da string LBUFFER , mas isso é um padrão regex ou algum híbrido regex globbing?
É parte dos padrões "extended_glob" específicos de zsh ?, ou seja, de man 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?

    
por the_velour_fog 03.10.2016 / 02:24

1 resposta

1

Parece que é uma expressão zsh "extended glob".

i.e. de man zshexpn

Globbing Flags
There are various flags which affect any text to their right up to the end of the enclosing group or to the end of the pattern; they require the EXTENDED_GLOB option. All take the form (#X) where X may have one of the following forms:

[...]
m
Set references to the match data for the entire string matched; this is similar to backreferencing and does not work in filename generation. The flag must be in effect at the end of the pat‐ tern, i.e. not local to a group. The parameters $MATCH, $MBEGIN and $MEND will be set to the string matched and to the indices of the beginning and end of the string, respectively. This is most useful in parameter substitutions, as otherwise the string matched is obvious.

For example,

       arr=(veldt jynx grimps waqf zho buck)
       print ${arr//(#m)[aeiou]/${(U)MATCH}}

forces all the matches (i.e. all vowels) into uppercase, print‐ ing 'vEldt jynx grImps wAqf zhO bUck'. Unlike backreferences, there is no speed penalty for using match references, other than the extra substitutions required for the replacement strings in cases such as the example shown.

e o operador # é o chamado "encerramento" ou operador de correspondência repetida, equivalente a * em regex

como explicado aqui link

Então, basicamente, essa expansão de parâmetro:

${LBUFFER%%(#m)[_a-zA-Z0-9]#}

iniciará uma referência anterior ao estilo regex começando em (#m) , onde qualquer padrão correspondente estará disponível em uma variável $MATCH como em um BRE ou $1 em um PCRE.
E como # é igual a * , [_a-zA-Z0-9]# corresponderá a zero ou muitos caracteres do conjunto de caracteres [_a-zA-Z0-9] .

    
por 03.10.2016 / 03:26

Tags