bash 정규 표현식이 \b를 지원하지 않는 이유가 있나요? [복사]

bash 정규 표현식이 \b를 지원하지 않는 이유가 있나요? [복사]

내가 아는 한, \bbash는 "단어 경계"를 나타내는 메타 시퀀스를 지원하지 않습니다.

if [[ $foo =~ .*\bWORD\b.* ]]; then

이 기능이 지원되지 않는 이유가 있나요?

bash에 대한 패치/풀 요청을 작성한다고 상상해 보세요. 구현될 수 없는 이유가 있습니까 \b("이 기능이 마음에 들지 않습니다" 등 제외)?

답변1

~에 따르면bash매뉴얼 페이지, 이 =~연산자는 POSIX 정규식 함수를 사용하는 것으로 보입니다.

연산자를 사용하면 =~오른쪽 문자열은 POSIX 확장 정규식 패턴으로 처리되어 그에 따라 일치됩니다(POSIX regcomp및 일반적으로 설명된 인터페이스 사용).regexecregex(3)

메타 \b시퀀스는Perl 정규식 구문POSIX의 일부가 아니므로 Bash에서 사용하는 라이브러리는 이를 지원하지 않는 것 같습니다. 따라서 Bash에서 이를 지원한다는 것은 라이브러리를 변경하는 것을 의미할 수 있으며, 이는 종종 심각한 부작용을 낳습니다.

이는 순전히 문법적 요소를 수용하기 위해 수행된 것 같지 않습니다.

답변2

먼저 Bash에 자체 RE 구현이 있는지, 아니면 시스템 라이브러리의 RE 구현을 사용하는지 확인하세요.

하지만 그렇습니다. \b일반적으로 Perl 정규식에서 비롯된 표준 정규식에서는 사용할 수 없는 다른 확장도 많이 포함하고 있습니다. GNU 시스템은 \s공백과 단어 문자를 지원하는 것으로 보이지만 숫자는 지원 \w하지 않습니다 \d. 왜 그 이상한 것들을 선택하기로 결정했는지는 모르겠지만, 전반적으로,모두Perl RE 기능은 RE 엔진을 더욱 복잡하게 만들 수 있으며 Perl 팬은 이를 좋아하지만 많은 표준 도구 작성자는 이를 원하지 않을 수 있습니다. 그러다가 전부는 아니고 이것저것 추가하기 시작하면 어디에 선을 그어야 할지 결정하는 것이 문제가 됩니다.

어쨌든 단어 테두리는 처음부터 비표준입니다. 일부 시스템에서는 \<및 가 \>왼쪽 및 오른쪽 경계선에 적용되어야 하지만 FreeBSD 및 Mac에서는 [[:<:]]및 가 필요합니다 [[:>:]].

공교롭게도 @steeldriver가 언급한 것처럼 \b적어도 제가 테스트했을 때 GNU에서도 작동하는 것 같습니다. Bash에서는 쉘의 구문 분석 프로세스로 인해 특수 문자가 난독화되는 것을 방지하기 위해 먼저 RE를 변수에 저장해야 합니다.

$ re='\bWORD\b'; if [[ WORD =~ $re ]]; then echo y; else echo n; fi
y
$ re='\<WORD\>'; if [[ WORD =~ $re ]]; then echo y; else echo n; fi
y
$ re='\bWORD\b'; if [[ WORDLESS =~ $re ]]; then echo y; else echo n; fi
n
$ re='\<WORD\>'; if [[ WORDLESS =~ $re ]]; then echo y; else echo n; fi
n

관련 정보