bash - extglob 두 번째 "0개 이상의" 연산자가 작동하지 않습니다.

bash - extglob 두 번째 "0개 이상의" 연산자가 작동하지 않습니다.

반면:

$ shopt -s extglob
$ TEST="    z abcdefg";echo ">>${TEST#*( )z*( )}<<"
>> abcdefg<<

문자 "a" 앞에 공백이 있는 이유는 무엇입니까? 두 번째도 *( )공간에 어울리게 하고 싶었는데 그렇게 하기엔 적합하지 않네요.

나는 다음과 같은 결과를 기대합니다:

$ echo ">>$(echo -n "${TEST}" | perl -pe "s/^ *z *//g")<<"
>>abcdefg<<

*( )다음 문자(예: "a")를 지정하면 두 번째 문자가 일치합니다.

$ shopt -s extglob
$ TEST="    z abcdefg";echo ">>${TEST#*( )z*( )a}<<"
>>bcdefg<<

히트 버전: GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)

답변1

${TEST#...}가장 짧은 문자열, z 뒤에 공백이 없는 문자열과 일치합니다. 당신은 ${TEST##...}가장 긴 일치를 원합니다 .

답변2

이는 탐욕스럽지 않은 하위 문자열 제거와 사용 중인 패턴 유형 간의 상호 작용으로 인해 발생합니다.

~에서배쉬 매뉴얼,

?(pattern-list)

주어진 패턴이 0개 또는 1개 일치합니다.

*(pattern-list)

주어진 패턴의 0개 이상의 발생과 일치합니다.

+(pattern-list)

주어진 패턴과 하나 이상 일치합니다.

내가 가장 좋아하는 bash 설명에서문자열 연산,

${string#substring}

$substring이전에 가장 짧은 일치 항목을 제거합니다 $string.

${string##substring}

$substring가장 긴 이전 일치 항목을 제거합니다 $string.

따라서 을 지정할 때 다음과 같이 ${TEST#*( )z*( )}말하는 것입니다. "0개 이상의 공백이 있는 가장 짧은 하위 문자열 a를 제거하고 z그 뒤에 0개 이상의 공백이 옵니다.

마지막 공백이 있는 일치 항목은 없는 항목보다 길기 때문에 마지막 공백은 일치하지 않습니다.

이 문제를 해결하려면 ${TEST##*( )z*( )}0개 이상의 공백으로 끝나는 가장 긴 접두사 일치를 사용하거나 ${TEST#*( )z+( )}하나 이상의 공백으로 끝나는 가장 짧은 접두사 일치를 사용할 수 있습니다(이는 공백 1개로 끝나는 가장 짧은 접두사 일치와 기능적으로 동일함).

답변3

is (perl) 정규 표현식을 모방하려면 regexnot a 를 사용하십시오 pattern.

$ test="    z abcdefg"
$ regex='^ *z *(.*)'
$ [[ $test =~ $regex ]]
$ echo ">>${BASH_REMATCH[1]}<<"
>>abcdefg<<

정규식은 전체 PCRE가 아닌 확장 정규식입니다.

관련 정보