Regular-Expression

zsh字元串模式匹配刪除空格

  • September 13, 2019

嘗試使用 解決程式碼高爾夫問題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//+( )!/!}

這不是通常的正則表達式語法中的正則表達式。這是一個萬用字元模式。sh 萬用字元模式不如正則表達式表達。Ksh、bash 和 zsh 具有與正則表達式一樣富有表現力的萬用字元模式,但語法不同。另請參閱為什麼我的正則表達式在 X 中有效,但在 Y 中無效?

在 zsh 中執行此操作的正常方法是打開該extended_glob選項(幾乎每個人幾乎一直都在這樣做)並使用與前面任意數量匹配的#萬用字元*(就像在通常的正則表達式語法中一樣)。

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

您的嘗試失敗有兩個原因。首先,*萬用字元模式表示“任何字元序列”。其次,非貪心匹配會破壞目的:它會導致沒有空間匹配。

在 ksh、bash aftershopt -s extglob和 zsh aftersetopt ksh_glob中,您可以使用*( )匹配零個或多個空格,或+( )匹配一個或多個空格。要麼在這裡做。

對於正常使用,您只需打開extended_glob. 對於程式碼高爾夫來說,這是一個相當高的代價。也許你可以縮小空間爆炸以循環爆炸:repeat $#a a=${a/ !/!}. 或者您可以輸入“zsh with extended_globturn on”類別,這是編寫 zsh 補全函式的語言。

引用自:https://unix.stackexchange.com/questions/541610