我可以在 zsh 參數擴展中使用什麼樣的模式?
在我的 zsh shell 腳本中,我
regexp-replace nname "_{2,}" "_"
成功地使用將多個“_”減少為一個,但是當我嘗試${nname//_{2,}/'_'}
zsh 時似乎與模式不匹配。
man zshexpn
是。不清楚。它提到了 globbing 模式,但顯然還有其他 POSIX 1003.2 正則表達式,例如${name//[^[:alnum:]]/"_"}
我的腳本中的 in work OK。動機
我正在尋找參數擴展等價於
regexp-replace nname "[^[:alnum:]]" "_" regexp-replace nname "_{2,}" "_" regexp-replace nname "_+$" "" regexp-replace nname "^_+" ""
zsh
zsh --version zsh 5.7.1 (x86_64-apple-darwin19.0)
${var//pattern/replacement}
正在使用 zsh 萬用字元模式,與用於文件名生成pattern
的萬用字元模式相同,也就是萬用字元模式的超集。語法也受and選項的影響。最初來自Korn shell。sh``kshglob``extendedglob``${var//pattern/replacement}
我建議啟用
extendedglob
(set -o extendedglob
在您的~/.zshrc
)中,它可以為您提供最多的功能(比標準 ERE 更多),但會在某些極端情況下以某些向後不兼容為代價。您會發現它記錄在
info zsh 'filename generation'
.ERE 和擴展 zsh 萬用字元之間映射的備忘單:
標準
sh
的:
.
->?
.*
->*
[...]
->[...]
zsh 擴展:
*
->#
+
->##
{x,y}
->(#cx,y)
(...|...)
->(...|...)
標準 ERE 中沒有的一些額外功能:
^pattern
(否定)x~y
(除了)<12-234>
匹配十進制數字範圍(#i)
不區分大小寫的匹配(#a2)
近似匹配允許最多 2 個錯誤。- 還有很多
萬用字元模式是錨定在主題的開頭還是結尾取決於使用的運算符。
- 球體、
case
模式[[ string = pattern ]]
和${var:#pattern}
都錨定在兩者f*.txt
上(將匹配foo.txt
,不匹配Xfoo.txtY
)${var#pattern}
並${var##pattern}
在一開始就錨定${var%pattern)
並${var%%pattern}
固定在最後${var/pattern/repl}
並且${var//pattern/repl}
沒有錨定,但可以使用${var/#pattern}
(start) 或${var/%pattern}
(end) 進行錨定。
(#s)
也(#e)
可以用作^
/$
(ERE) 或\A
/\z
(PCRE) 的等價物。重複運算符 (
#
,##
,*
,(#cx,y)
,<x-y>
) 是否貪心也取決於運算符(貪心與##
,%%
,//
,/
而不是#
,%
),可以通過S
參數擴展標誌進行更改。所以對於你的例子:
regexp-replace nname "[^[:alnum:]]" "_"
:${var//[^[:alnum:]]/_}
regexp-replace nname "_{2,}" "_"
:${var//_(#c2,)/_}
regexp-replace nname "_+$" ""
:${var%%_#}
或${var/%_#}
(這裡使用#
等價*
物,您可以使用##
等價物,+
但在這種情況下不會有任何區別)。regexp-replace nname "^_+" ""
:${var##_#}
或${var/#_#}
在這裡,您可以將它們與
${${${var//[^[:alnum:]]##/_}#_}%_}
(將非alnums 序列轉換為_
並刪除最終的前導或尾隨_
)。另一種方法可能是提取所有的 alnums 序列並將它們與 連接起來
_
,使用這個 hack:words=() : ${var//(#m)[[:alnum:]]##/${words[1+$#words]::=$MATCH}} var=${(j:_:)words}
regexp-replace``[[ $var =~ pattern ]]
它本身是一個循環呼叫的可自動載入函式。請注意,因此,它不能與^
錨點或單詞邊界或後視運算符(如果使用該rematchpcre
選項)一起正常工作:$ a='aaab'; regexp-replace a '^a' x; echo "$a" xxxb $ a='abab'; regexp-replace a '\<ab' '<$MATCH>'; echo $a <ab><ab>
(在第一個範例中,在該循環
^a
中依次匹配aaab
,aab
, , )。ab``b