해결하려고 노력 중코드 골프 질문사용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// #!/!}
두 가지 이유로 시도가 실패했습니다. 첫째, *
와일드카드 패턴은 "모든 문자 시퀀스"를 의미합니다. 둘째, 탐욕스럽지 않은 일치는 목적을 무너뜨립니다. 즉, 일치하는 공간이 없습니다.
ksh, bash after shopt -s extglob
및 zsh after 에서는 을 사용하여 0개 이상의 공백을 일치시키거나 하나 이상의 공백을 일치시킬 setopt ksh_glob
수 있습니다 . 여기서 하세요.*( )
+( )
일반적인 사용을 위해서는 전원을 켜기만 하면 됩니다 extended_glob
. 코드 골프에 지불하는 비용은 꽤 높습니다. 어쩌면 스페이스뱅을 루프의 뱅으로 축소할 수도 있습니다 repeat $#a a=${a/ !/!}
. 또는 extended_glob
zsh 완성 기능이 작성된 언어인 "open zsh" 범주로 이동할 수 있습니다 .