
我遇到了一個包含此參數擴充功能的 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]