Zsh文字列パターンマッチングスペースを削除する

Zsh文字列パターンマッチングスペースを削除する

解決しようとしていますコードゴルフの質問使用zshしかし、私の正規表現は機能しません。

必要
入力文字列が与えられたら、文字のすぐ$1左にあるすべてのスペースを削除します。!

例:

Input ($1)          Expected Result:
" ! a! !b c!d !" => "! a!!b c!d!"
"a    !"         => "a!"
"!    a"         => "!    a"
"!    !    !"    => "!!!"
"! "             => "! "

私は以下を使って解決策が欲しいです。zsh組み込みの場合にのみこれが私が得ることができる最も近いものです:

<<<${(S)1// *!/!}

残念ながら -オンラインでお試しください- その結果

!!!b!d!
!    a
!!!
! 

ご覧のように、ゲームの過度の熱心さのために最初の行が壊れています*。 zshドキュメント(ガイドライン5.9.2および5.9.3)この時点でかなり混乱しています。

優先順位+演算子も機能しません。 :(<<<${(S)1//+( )!/!}

答え1

これは一般的な正規表現構文の正規表現ではありません。これはワイルドカードパターンです。 Shワイルドカードパターンは正規表現よりも表現力が低下します。 Ksh、bash、zshには、正規表現と同じくらい表現力豊かなワイルドカードパターンがありますが、構文は異なります。また、見ることができます私の正規表現がXでは動作しますが、Yでは動作しないのはなぜですか?

zshでこれを行う一般的な方法は、次を開くことです。extended_globオプション(ほとんどの人は常にこれを行います)#ワイルドカード*通常の正規表現構文と同様に、前のコンテンツと一致します。

setopt extended_glob
no_spaces_before_bang=${original_string// #!/!}

2つの理由で試みが失敗しました。まず、*ワイルドカードパターンは「すべての文字シーケンス」を意味します。第二に、貪欲ではない一致は目的を崩します。つまり、一致するスペースがありません。

ksh、bash after shopt -s extglob、およびzsh afterでは、を使用してゼロ以上のスペースを一致させることも、1つ以上のスペースを一致させることもsetopt ksh_globできます。ここでください。*( )+( )

一般的な使用には、電源を入れるだけですextended_glob。コードゴルフに支払う費用はかなり高いです。たぶんスペースバンをループのバンに縮小することもできますrepeat $#a a=${a/ !/!}。あるいは、extended_globzsh補完機能が作成された言語である「open zsh」カテゴリに移動することもできます。

関連情報