この zsh パラメータ拡張はどのように機能しますか?

この zsh パラメータ拡張はどのように機能しますか?

このパラメータ拡張を含むzshスクリプトを見つけました

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

この表現がどのような文脈で使われているのか知りたい人は、vimのような略語を提供するzleウィジェット関数

その基本形は明らかに接尾辞のトリムです。つまり${name%%pattern}

つまりman zshexpn、パラメータ拡張から

   ${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;
     [...]

に関してパラメータ拡張フラグ (#m): から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.

部分に関しては[_a-zA-Z0-9]#、これは明らかに文字列の末尾から削除されるパターンですLBUFFERが、これは正規表現パターンですか、それとも正規表現グロブのハイブリッドですか?
これはzsh固有の「extended_glob」パターンの一部ですか?つまり、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.)

この zsh パラメータ拡張は何をしますか?

答え1

それは zsh の「拡張 glob」表現のようです。

つまりman zshexpn

グロブ フラグ 囲ん
でいるグループの終わりまで、またはパターンの終わりまでの右側のテキストに影響を与えるさまざまなフラグがあります。これらのフラグには EXTENDED_GLOB オプションが必要です。すべてのフラグは (#X) という形式を取ります。ここで、X は次のいずれかの形式になります。

[...]
m
一致した文字列全体の一致データへの参照を設定します。これはバックリファレンスに似ており、ファイル名の生成では機能しません。フラグはパターンの最後で有効である必要があります。つまり、グループに対してローカルではありません。パラメータ $MATCH、$MBEGIN、および $MEND は、それぞれ一致した文字列と文字列の先頭と末尾のインデックスに設定されます。これは、パラメータ置換で最も役立ちます。そうしないと、一致した文字列が明らかになります。

例えば、

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

一致したすべての文字(つまり、すべての母音)を大文字に変換し、`vEldt jynx grImps wAqf zhO buck' と出力します。後方参照とは異なり、一致参照を使用する場合、示されている例のような場合に置換文字列に必要な追加の置換を除いて、速度の低下はありません。

そして、#演算子はいわゆる「閉包」または繰り返し一致演算子であり、*正規表現の

ここで説明されているようにhttp://zsh.sourceforge.net/ガイド/zshguide05.html#l139

つまり、基本的にこのパラメータ拡張は次のようになります。

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

は、 から始まる正規表現スタイルの後方参照を開始します。ここで、一致したパターンは、 BRE やPCRE のように(#m)変数で使用できます。 は とまったく同じなので、は文字セット の 0 個以上の文字と一致します。$MATCH\1$1
#*[_a-zA-Z0-9]#[_a-zA-Z0-9]

関連情報