這個 zsh 參數擴充是如何運作的?

這個 zsh 參數擴充是如何運作的?

我遇到了一個包含此參數擴充功能的 zsh 腳本

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

對於任何想知道這個表達所處的上下文的人來說,它是zle 小工具功能,提供類似 vim 的縮寫

其基本形式顯然是後綴修剪。 IE${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/Guide/zshguide05.html#l139

所以基本上,這個參數擴充:

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

將啟動正規表示式樣式的反向引用,從任何符合的模式在變數(如BRE 或PCRE)(#m)中可用的位置開始。 因為就像,將匹配字元集中的零個或多個字元。$MATCH\1$1
#*[_a-zA-Z0-9]#[_a-zA-Z0-9]

相關內容