Tentando resolver um problema de code-golf usando zsh
, mas meu regex não está funcionando corretamente.
Requisito
Dada a string de entrada $1
, exclua todos os espaços imediatamente à esquerda de qualquer !
caractere.
Exemplos:
Input ($1) Expected Result:
" ! a! !b c!d !" => "! a!!b c!d!"
"a !" => "a!"
"! a" => "! a"
"! ! !" => "!!!"
"! " => "! "
Eu quero uma solução usando zsh
apenas builtins, este foi o mais próximo que consegui:
<<<${(S)1// *!/!}
Infelizmente - tente online - isso resulta em
!!!b!d!
! a
!!!
!
Como você pode ver, a primeira linha foi mutilada com muito entusiasmo pela *
partida. A documentação do zsh ( seg. 5.9.2 e 5.9.3 do Guia ) é bastante confusa neste ponto.
o +
operador de precedência também não funciona :(<<<${(S)1//+( )!/!}
Isso não é uma expressão regular na sintaxe regex usual. É um padrão curinga. Os padrões curinga Sh são menos expressivos do que as expressões regulares. Ksh, bash e zsh têm padrões curinga que são tão expressivos quanto expressões regulares, mas com sintaxes diferentes. Veja também Por que minha expressão regular funciona em X mas não em Y?
A maneira normal de fazer isso no zsh seria ativar a
extended_glob
opção (que praticamente todo mundo faz praticamente o tempo todo) e usar o#
curinga que corresponde a qualquer número anterior (como*
na sintaxe regex usual).Sua tentativa falhou por dois motivos. Primeiro,
*
em padrões curinga significa “qualquer sequência de caracteres”. Em segundo lugar, a correspondência não gananciosa anularia o propósito: não faria com que nenhum espaço fosse correspondido.Em ksh, e em bash after
shopt -s extglob
, e em zsh aftersetopt ksh_glob
, você pode usar*( )
para corresponder a zero ou mais espaços, ou+( )
para corresponder a um ou mais espaços. Qualquer um faria aqui.Para uso normal, basta ligar
extended_glob
. Para o golfe de código, esse é um preço bastante alto a pagar. Talvez você possa encolher espaço-estrondo para bater em um loop:repeat $#a a=${a/ !/!}
. Ou você pode entrar na categoria “zsh comextended_glob
ativado”, que é o idioma no qual as funções de conclusão do zsh são escritas.