저는 이 동작을 이해하는 데 정말 어려움을 겪고 있습니다.
stackExchange@test:~$ if [[ "two words" =~ \bwords ]]; then echo hi; fi; #(I'd expect this one worked)
stackExchange@test:~$ if [[ "two words" =~ \\bwords ]]; then echo hi; fi; #(or at least this one...)
stackExchange@test:~$ if [[ "two words" =~ \\\bwords ]]; then echo hi; fi;
stackExchange@test:~$ if [[ "two words" =~ \\\\bwords ]]; then echo hi; fi;
stackExchange@test:~$ put_in_a_variable=\\bwords
stackExchange@test:~$ if [[ "two words" =~ $put_in_a_variable ]]; then echo hi; fi;
hi
stackExchange@test:~$
\bword
내 변수가 조건식의 패턴 부분에 포함되고 확장된다는 것을 알고 있지만 인라인 쉘 이스케이프를 사용하여 동일한 동작을 달성하는 것이 왜 불가능해 보이는지 정말로 이해할 수 없습니다.
나는 그런 짓을 하고 싶지 않다 if [[ "two words" =~ $(echo \\bwords) ]]; then echo hi; fi;
. 너무 이상하다.
고마워요,
프란시스코
답변1
정규식 부분에서 백슬래시의 목적은 다음 [[ str =~ rex ]]
과 같습니다.인용하다다음 문자(작은따옴표로 묶은 것처럼), bash 및 버전 3.2부터는 문자 그대로 일치하도록 지시합니다(1). b
특별하지 않기 때문에 \b
그냥 b
, 그러나 '\'
, "\\"
또는 리터럴 백슬래시와 일치시키기 위해 \\
될 것입니다 :\\
[[ abwords =~ \bwords ]] && echo "<$BASH_REMATCH>"
<bwords>
[[ 'a\bwords' =~ \\bwords ]] && echo "<$BASH_REMATCH>"
<\bwords>
# conversely, '|' is just like \|
[[ 'a|words' =~ a'|'words ]] && echo "<$BASH_REMATCH>"
<a|words>
정규식을 변수에 넣는 아이디어가 좋네요. 또 다른 방법은 래퍼 함수를 사용하는 것입니다.
rematch() [[ $1 =~ $2 ]]
if rematch 'two words' '\bwords\b'; then
echo "<$BASH_REMATCH>"
fi
<words>
어쨌든 이러한 해결 방법을 적용한 후에는 \b
비표준 확장 정규식 연산자(perl에서 제공됨)이므로 작동 여부는 시스템의 정규식 라이브러리가 이를 지원하는지 여부에 따라 달라집니다. 시스템에 따라 \<
/ \>
또는 [[:<:]]
/ 와 같은 단어 경계 연산자에 대한 대체 구문을 사용하는 것이 더 나을 수도 있습니다 [[:>:]]
.
(1): 기록된 대로수동:
패턴의 모든 부분을 인용하여 인용된 부분을 문자열로 일치시킬 수 있습니다.
쉘에서 문자는 다음과 같습니다.선두실제로는특별한 마크, 따라서 파서에 의한 후속 처리는 문자열의 일부가 인용되었는지 여부에 따라 결정될 수 있습니다.