¿Cómo funciona esta expansión de parámetros zsh?

¿Cómo funciona esta expansión de parámetros zsh?

Me encontré con un script zsh que contiene esta expansión de parámetros.

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

Para cualquiera que quiera saber el contexto en el que vive esta expresión, es parte de unFunción de widget zle que proporciona abreviaturas similares a vim

Su forma básica es obviamente un recorte de sufijo. es decir${name%%pattern}

es decir, desde man zshexpn- EXPANSIÓN 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;
     [...]

con respecto abandera de expansión de parámetros (#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.

Con respecto a la [_a-zA-Z0-9]#parte, este es obviamente el patrón que se elimina del final de la LBUFFERcadena, pero ¿es este un patrón de expresiones regulares o algún híbrido globbing de expresiones regulares?
¿Es parte de los patrones "extended_glob" específicos de zsh?, es decir, 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.)

¿Qué hace esta expansión de parámetros zsh?

Respuesta1

Parece que es una expresión zsh "glob extendida".

es decir, deman zshexpn

Banderas globales
Hay varias banderas que afectan cualquier texto a su derecha hasta el final del grupo circundante o hasta el final del patrón; Requieren la opción EXTENDED_GLOB. Todos toman la forma (#X) donde X puede tener una de las siguientes formas:

[...]
m
Establece referencias a los datos coincidentes para toda la cadena coincidente; esto es similar a la referencia inversa y no funciona en la generación de nombres de archivos. La bandera debe estar vigente al final del patrón, es decir, no localmente a un grupo. Los parámetros $MATCH, $MBEGIN y $MEND se establecerán en la cadena coincidente y en los índices del principio y final de la cadena, respectivamente. Esto es más útil en sustituciones de parámetros, ya que de lo contrario la cadena coincidente es obvia.

Por ejemplo,

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

fuerza todas las coincidencias (es decir, todas las vocales) a mayúsculas, imprimiendo `vEldt jynx grImps waqf zhO buck'. A diferencia de las referencias retrospectivas, no hay ninguna penalización de velocidad por usar referencias coincidentes, aparte de las sustituciones adicionales necesarias para las cadenas de reemplazo en casos como el ejemplo que se muestra.

y el #operador es el llamado operador de "cierre" o de coincidencia repetida, equivalente a *en expresiones regulares

como se explica aquíhttp://zsh.sourceforge.net/Guide/zshguide05.html#l139

Básicamente, esta expansión de parámetros:

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

iniciará una referencia inversa de estilo de expresión regular comenzando en (#m)donde cualquier patrón coincidente estará disponible en una variable $MATCHcomo \1en un BRE o$1 en un PCRE.
Y como #es así *, [_a-zA-Z0-9]#coincidirá con cero o muchos caracteres del conjunto de caracteres [_a-zA-Z0-9].

información relacionada