私のzshシェルスクリプトでregexp-replace nname "_{2,}" "_"
複数の「_」を1つに正常に減らしましたが、zshを試してみるとパターン${nname//_{2,}/'_'}
と一致しないようです。
man zshexpn
はい。わからない。これにはワイルドカードパターンが記載されていますが、${name//[^[:alnum:]]/"_"}
私のスクリプトで正しく動作するような他のPOSIX 1003.2正規表現があるようです。
やる気
次のパラメータ拡張を探しています。
regexp-replace nname "[^[:alnum:]]" "_"
regexp-replace nname "_{2,}" "_"
regexp-replace nname "_+$" ""
regexp-replace nname "^_+" ""
扱いにくい
zsh --version
zsh 5.7.1 (x86_64-apple-darwin19.0)
答え1
${var//pattern/replacement}
zshワイルドカードパターンの使用pattern
(使用されているものと同じ)ファイル名の生成ワイルドカードとも呼ばれ、sh
ワイルドカードパターンの親セットです。構文はkshglob
およびextendedglob
オプションの影響も受けます。もともと${var//pattern/replacement}
Kornシェルに由来していました。
あなたの場合はextendedglob
それを有効にすることをお勧めします。これは標準EREよりも多くの機能を提供しますが、いくつかの特殊なケースでは以前のバージョンとの互換性がなくなる可能性があります。set -o extendedglob
~/.zshrc
ログインしていることがわかりますinfo zsh 'filename generation'
。
EREと拡張zshワイルドカード間のマッピングのためのチートシート:
基準sh
:
.
->?
.*
->*
[...]
->[...]
zsh 拡張子:
*
->#
+
->##
{x,y}
->(#cx,y)
(...|...)
->(...|...)
一部のアドインは標準 ERE では使用できません。
^pattern
(否定的な)x~y
(とは別に)<12-234>
素数範囲一致(#i)
大文字と小文字を区別しない一致(#a2)
おおよその一致では、最大2つのエラーが許可されます。- もっとあります
ワイルドカードパターンがトピックの先頭に固定されているのか、最後に固定されているのかは、使用する演算子によって異なります。
- Glob、
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}
${var/%pattern}
(#s)
/(ERE)または/(PCRE)と同等に(#e)
使用することもできます。^
$
\A
\z
反復演算子(#
、、、、、、)が欲張りであるかどうかは、演算子によって異なり、(、欲求、、欲張りではない##
)*
パラメータ拡張フラグ(#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:]]##/_}#_}%_}
(alnum以外のシーケンスを変換し_
、最後の先行または末尾のシーケンスを削除_
)。
_
もう1つのアプローチは、次のハッキングを使用してすべてのalnumsシーケンスを抽出し、それを組み合わせることです。
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